Product placements and openings

This commit is contained in:
Thomas Krijnen
2019-09-19 10:11:01 +02:00
parent 3cde411e1b
commit 1f4bc28e2b
5 changed files with 94 additions and 15 deletions
@@ -55,6 +55,9 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonom
for (auto& c : collection->children) { for (auto& c : collection->children) {
convert(c, r); convert(c, r);
} }
for (auto i = s; i < r.size(); ++i) {
r[i].prepend(collection->matrix);
}
return r.size() > s; return r.size() > s;
} }
@@ -2104,17 +2104,36 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ifcopen
TopoDS_Shape a; TopoDS_Shape a;
TopTools_ListOfShape b; TopTools_ListOfShape b;
taxonomy::style first_item_style;
for (auto& c : br->children) { for (auto& c : br->children) {
// AbstractKernel::convert(c, results);
// continue;
ifcopenshell::geometry::ConversionResults cr; ifcopenshell::geometry::ConversionResults cr;
// @todo half-space detection // @todo half-space detection
AbstractKernel::convert(c, cr); AbstractKernel::convert(c, cr);
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) { if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
// @todo A will be null on union/intersection, intended? // @todo A will be null on union/intersection, intended?
flatten_shape_list(cr, a, false); flatten_shape_list(cr, a, false);
first_item_style = ((taxonomy::geom_item*)c)->surface_style;
if (!first_item_style.diffuse && c->kind() == taxonomy::COLLECTION) {
first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style;
}
} else { } else {
for (auto& r : cr) { for (auto& r : cr) {
auto oshp = (OpenCascadeShape*)r.Shape(); auto S = ((OpenCascadeShape*)r.Shape())->shape();
b.Append(oshp->shape()); gp_GTrsf trsf;
convert(&r.Placement(), trsf);
// @todo it really confuses me why I cannot use Moved() here instead
S.Location(S.Location() * trsf.Trsf());
b.Append(S);
/*results.emplace_back(ConversionResult(
r.ItemId(),
ifcopenshell::geometry::taxonomy::matrix4(),
new OpenCascadeShape(S),
r.Style()
));*/
} }
} }
first = false; first = false;
@@ -2125,11 +2144,21 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ifcopen
return false; return false;
} }
/*
TopoDS_Compound r;
BRep_Builder B;
B.MakeCompound(r);
B.Add(r, a);
for (auto& bb : b) {
B.Add(r, bb);
}
*/
results.emplace_back(ConversionResult( results.emplace_back(ConversionResult(
br->instance->data().id(), br->instance->data().id(),
br->matrix, br->matrix,
new OpenCascadeShape(r), new OpenCascadeShape(r),
br->surface_style br->surface_style.diffuse ? br->surface_style : first_item_style
)); ));
return true; return true;
} }
@@ -2261,4 +2290,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, ifcopenshell::g
new OpenCascadeShape(shape), new OpenCascadeShape(shape),
face->surface_style face->surface_style
)); ));
return true;
} }
@@ -218,7 +218,9 @@ namespace kernels {
public: public:
OpenCascadeKernel() OpenCascadeKernel()
: AbstractKernel("opencascade") : AbstractKernel("opencascade")
, faceset_helper_(nullptr) {} , faceset_helper_(nullptr)
// @todo
, precision_(1.e-5) {}
OpenCascadeKernel(const OpenCascadeKernel& other) OpenCascadeKernel(const OpenCascadeKernel& other)
: AbstractKernel("opencascade") { : AbstractKernel("opencascade") {
+41 -5
View File
@@ -306,9 +306,39 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcDirection* inst) {
taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) { taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) {
auto openings = find_openings(inst); auto openings = find_openings(inst);
auto n = map_to_collection<taxonomy::node>(this, openings); // @todo const cast
n->matrix = as<taxonomy::matrix4>(map(inst->ObjectPlacement())); auto reps = inst->data().file->traverse((IfcSchema::IfcProduct*) inst, 2)->as<IfcSchema::IfcRepresentation>();
return n; IfcSchema::IfcRepresentation* body = nullptr;
for (auto& rep : *reps) {
if (rep->RepresentationIdentifier() == "Body") {
body = rep;
}
}
if (!body) {
return nullptr;
}
auto c = new taxonomy::collection;
c->matrix = as<taxonomy::matrix4>(map(inst->ObjectPlacement()));
if (openings->size()) {
auto ci = c->matrix.components.inverse();
IfcEntityList::ptr operands(new IfcEntityList);
operands->push(body);
operands->push(openings);
auto n = map_to_collection<taxonomy::boolean_result>(this, operands);
std::for_each(n->children.begin() + 1, n->children.end(), [&ci](taxonomy::item* i) {
((taxonomy::geom_item*)i)->matrix.components = ci * ((taxonomy::geom_item*)i)->matrix.components;
});
n->operation = taxonomy::boolean_result::SUBTRACTION;
// @todo one indirection too many
n->instance = inst;
c->children = { n };
} else {
c->children = { map(body) };
}
return c;
} }
taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) {
@@ -515,7 +545,10 @@ IfcEntityList::ptr mapping::find_openings(const IfcSchema::IfcProduct* product)
IfcEntityList::ptr openings(new IfcEntityList); IfcEntityList::ptr openings(new IfcEntityList);
if (product->declaration().is(IfcSchema::IfcElement::Class()) && !product->declaration().is(IfcSchema::IfcOpeningElement::Class())) { if (product->declaration().is(IfcSchema::IfcElement::Class()) && !product->declaration().is(IfcSchema::IfcOpeningElement::Class())) {
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product; IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
openings = element->HasOpenings()->generalize(); auto rels = element->HasOpenings();
for (auto& rel : *rels) {
openings->push(rel->RelatedOpeningElement());
}
} }
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements? // Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
@@ -526,7 +559,10 @@ IfcEntityList::ptr mapping::find_openings(const IfcSchema::IfcProduct* product)
IfcSchema::IfcObjectDefinition* rel_obdef = (*decomposes->begin())->as<IfcSchema::IfcRelAggregates>()->RelatingObject(); IfcSchema::IfcObjectDefinition* rel_obdef = (*decomposes->begin())->as<IfcSchema::IfcRelAggregates>()->RelatingObject();
if (rel_obdef->declaration().is(IfcSchema::IfcElement::Class()) && !rel_obdef->declaration().is(IfcSchema::IfcOpeningElement::Class())) { if (rel_obdef->declaration().is(IfcSchema::IfcElement::Class()) && !rel_obdef->declaration().is(IfcSchema::IfcOpeningElement::Class())) {
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)rel_obdef; IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)rel_obdef;
openings->push(element->HasOpenings()->generalize()); auto rels = element->HasOpenings();
for (auto& rel : *rels) {
openings->push(rel->RelatedOpeningElement());
}
} }
obdef = rel_obdef; obdef = rel_obdef;
+12 -5
View File
@@ -34,18 +34,24 @@ ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create
ifcopenshell::geometry::Representation::BRep* shape; ifcopenshell::geometry::Representation::BRep* shape;
ifcopenshell::geometry::ConversionResults shapes; ifcopenshell::geometry::ConversionResults shapes;
/*
auto rep_item = mapping_->map(representation); auto rep_item = mapping_->map(representation);
// @todo should map() throw an exception instead? // @todo should map() throw an exception instead?
if (rep_item == nullptr) { if (rep_item == nullptr) {
return nullptr; return nullptr;
} }
*/
// @todo decide how to get placement from product // @todo how to combine product_node and rep_item?
auto placement = (taxonomy::geom_item*) mapping_->map(product); auto product_node = (taxonomy::geom_item*) mapping_->map(product);
if (placement == nullptr) { if (product_node == nullptr) {
return nullptr; return nullptr;
} }
kernel_->convert(rep_item, shapes);
auto place = taxonomy::matrix4();
std::swap(place, product_node->matrix);
kernel_->convert(product_node, shapes);
shape = new ifcopenshell::geometry::Representation::BRep(s, representation_id_builder.str(), shapes); shape = new ifcopenshell::geometry::Representation::BRep(s, representation_id_builder.str(), shapes);
@@ -57,7 +63,8 @@ ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create
guid, guid,
// @todo // @todo
"", "",
placement->matrix, place,
// product_node->matrix,
boost::shared_ptr<ifcopenshell::geometry::Representation::BRep>(shape), boost::shared_ptr<ifcopenshell::geometry::Representation::BRep>(shape),
product product
); );