define the vector sass [0] as a std::vector<std::unique_ptr<ShapeAnalysis_Surface>>

https: //github.com/IfcOpenShell/IfcOpenShell/issues/1975
Co-Authored-By: Dion Moult <dion@thinkmoult.com>
Co-Authored-By: Thomas Krijnen <1096535+aothms@users.noreply.github.com>
This commit is contained in:
Benjamin Dahl
2022-01-13 01:24:57 +01:00
committed by Thomas Krijnen
parent 189e566740
commit 81016f3110
+119 -119
View File
@@ -356,7 +356,7 @@ namespace {
while (j < N) {
double u = u0 + (u1 - u0) * i / N;
double v = v0 + (v1 - v0) * j / N;
i++;
if (i == N) {
i = 0;
@@ -451,7 +451,7 @@ namespace {
BRepTopAdaptor_FClass2d cls(g, BRep_Tool::Tolerance(g));
gp_Pnt test;
while (pgen(test)) {
while (pgen(test)) {
gp_Vec d = test.XYZ() - p1->Position().Location().XYZ();
double u = d.Dot(p1->Position().XDirection());
double v = d.Dot(p1->Position().YDirection());
@@ -699,14 +699,14 @@ namespace {
const TopoDS_Face& f_b = TopoDS::Face(b_faces(k));
Bnd_Box B;
BRepBndLib::Add(f_b, B);
// Query tree using b_face bounding box
for (auto& i : tree.select_box(B, false)) {
const TopoDS_Face& f_a = TopoDS::Face(a_faces(i));
TopTools_IndexedMapOfShape f_a_vertices;
TopExp::MapShapes(f_a, TopAbs_VERTEX, f_a_vertices);
BRepGProp_Face prop_a(f_a);
BRepGProp_Face prop_b(f_b);
@@ -744,7 +744,7 @@ namespace {
if (v_a.IsOpposite(v_b, 1.e-5)) {
// Check if faces are co-planar
if ((p_b.XYZ() - p_a.XYZ()).Dot(v_a.XYZ()) <= prec) {
TopTools_IndexedMapOfShape f_b_vertices;
TopExp::MapShapes(f_b, TopAbs_VERTEX, f_b_vertices);
@@ -853,7 +853,7 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
return false;
}
TopTools_ListIteratorOfListOfShape face_iterator;
TopTools_ListIteratorOfListOfShape face_iterator;
bool has_shared_edges = false;
TopTools_MapOfShape edge_set;
@@ -904,7 +904,7 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
sewing_builder.Perform();
shape = sewing_builder.SewedShape();
}
BRepCheck_Analyzer ana(shape);
valid_shell = ana.IsValid();
@@ -985,7 +985,7 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
B.Add(complete_shape, result_shape);
}
}
TopExp_Explorer loose_faces(shape, TopAbs_FACE, TopAbs_SHELL);
for (; loose_faces.More(); loose_faces.Next()) {
@@ -1005,7 +1005,7 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
} else {
Logger::Error("Failed to sew faceset");
}
return valid_shell;
}
@@ -1022,21 +1022,21 @@ const TopoDS_Shape& IfcGeom::Kernel::ensure_fit_for_subtraction(const TopoDS_Sha
if (!is_comp) {
return solid = shape;
}
if (!create_solid_from_compound(shape, solid)) {
return solid = shape;
}
// If the SEW_SHELLS option had been set this precision had been applied
// at the end of the generic convert_shape() call.
const double precision = getValue(GV_PRECISION);
apply_tolerance(solid, precision);
return solid;
}
// @nb this function is only in use on older versions of occt.
bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
// TODO: Refactor convert_openings() convert_openings_fast() and convert(IfcBooleanResult) to use
@@ -1068,7 +1068,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
IfcSchema::IfcProductRepresentation* prodrep = fes->Representation();
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
convert_shapes(*it2,opening_shapes);
}
@@ -1100,7 +1100,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity);
}
TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, opening_shape_gtrsf);
double opening_volume;
if (Logger::LOG_WARNING >= Logger::Verbosity()) {
opening_volume = shape_volume(opening_shape);
@@ -1183,7 +1183,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
} catch (...) {
Logger::Error("Shape healing failed on opening subtraction result", entity);
}
BRepCheck_Analyzer analyser(brep_cut_result);
bool is_valid = analyser.IsValid() != 0;
if ( is_valid ) {
@@ -1210,9 +1210,9 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
}
#if OCC_VERSION_HEX < 0x60900
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
// Create a compound of all opening shapes in order to speed up the boolean operations
TopoDS_Compound opening_compound;
BRep_Builder builder;
@@ -1243,7 +1243,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
IfcGeom::IfcRepresentationShapeItems opening_shapes;
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
convert_shapes(*it2,opening_shapes);
}
@@ -1273,7 +1273,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
bool is_valid = false;
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
BRepCheck_Analyzer analyser(brep_cut_result);
is_valid = analyser.IsValid() != 0;
if ( is_valid ) {
@@ -1287,7 +1287,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
Logger::Message(Logger::LOG_WARNING,"Subtracting combined openings compound failed:",entity);
return false;
}
}
return true;
}
@@ -1325,7 +1325,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
if (ds->size() == 1) {
relative = (*ds->begin())->RelatingObject()->as<IfcSchema::IfcProduct>();
}
}
}
set_conversion_placement_rel_to_instance(relative);
*/
@@ -1375,7 +1375,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
// Iterate over the shapes of the IfcProduct
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
bool is_manifold = Kernel::is_manifold(it3->Shape());
if (!is_manifold) {
@@ -1453,7 +1453,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& face) {
TopoDS_Wire wire = w;
TopTools_ListOfShape results;
if (wire_intersections(wire, results)) {
Logger::Warning("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected");
@@ -1490,7 +1490,7 @@ bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& fa
return false;
}
face = mf.Face();
return true;
}
@@ -1603,7 +1603,7 @@ bool IfcGeom::Kernel::convert_curve_to_wire(const Handle(Geom_Curve)& curve, Top
bool IfcGeom::Kernel::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) {
TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
for ( int i = 0; i < numVerts; i ++ ) {
gp_XY xy (verts[2*i],verts[2*i+1]);
trsf.Transforms(xy);
@@ -1925,7 +1925,7 @@ bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& sha
sew.Add(BRepBuilderAPI_MakeFace(w));
previous_edge.Nullify();
}
sew.Perform();
shape = sew.SewedShape();
@@ -1952,7 +1952,7 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
builder.MakeCompound(compound);
result = TopoDS_Shape();
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
TopoDS_Shape merged;
const TopoDS_Shape& s = it->Shape();
@@ -1982,11 +1982,11 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if ( is_valid ) {
result = fused;
}
}
}
}
} else {
@@ -2006,7 +2006,7 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
return success;
}
void IfcGeom::Kernel::remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
if (tol <= 0.) tol = getValue(GV_PRECISION);
tol *= tol;
@@ -2091,7 +2091,7 @@ void IfcGeom::Kernel::sequence_of_point_to_wire(const TColgp_SequenceOfPnt& p, T
if (close) {
builder.Close();
}
w = builder.Wire();
w = builder.Wire();
}
IfcSchema::IfcRelVoidsElement::list::ptr IfcGeom::Kernel::find_openings(IfcSchema::IfcProduct* product) {
@@ -2139,7 +2139,7 @@ const IfcSchema::IfcMaterial* IfcGeom::Kernel::get_single_material_association(c
IfcSchema::IfcMaterialSelect* associated_material = (*associated_materials->begin())->RelatingMaterial();
single_material = associated_material->as<IfcSchema::IfcMaterial>();
// NB: IfcMaterialLayerSets are also considered, regardless of --enable-layerset-slicing. Picking
// NB: IfcMaterialLayerSets are also considered, regardless of --enable-layerset-slicing. Picking
// the first material (in accordance with other viewers) when layerset-slicing is disabled.
if (!single_material && associated_material->as<IfcSchema::IfcMaterialLayerSetUsage>()) {
IfcSchema::IfcMaterialLayerSet* layerset = associated_material->as<IfcSchema::IfcMaterialLayerSetUsage>()->ForLayerSet();
@@ -2187,7 +2187,7 @@ IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_produc
break;
}
}
if (styles.size() > 1) {
// If there's only a single layer there is no need to manipulate geometries.
bool success = true;
@@ -2261,10 +2261,10 @@ IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_produc
} catch (const std::exception& e) {
Logger::Error(e);
}
const std::string name = product->Name().get_value_or("");
const std::string guid = product->GlobalId();
gp_Trsf trsf;
try {
if (product->ObjectPlacement()) {
@@ -2313,8 +2313,8 @@ IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_representation_and_produc
} catch (const std::exception& e) {
Logger::Message(Logger::LOG_ERROR, std::string("Error processing openings for: ") + e.what() + ":", product);
caught_error = true;
} catch(...) {
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product);
} catch(...) {
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product);
}
if (caught_error && opened_shapes.size() < shapes.size()) {
@@ -2463,14 +2463,14 @@ IfcSchema::IfcProduct::list::ptr IfcGeom::Kernel::products_represented_by(const
for (IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it) {
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
// It will be changed into an ABSTRACT supertype in future releases of IFC.
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
products->push((*it)->data().getInverse((&IfcSchema::IfcProduct::Class()), -1)->as<IfcSchema::IfcProduct>());
}
IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
if (products->size() && maps->size()) {
@@ -2527,10 +2527,10 @@ IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_processed_representation(
} catch (const std::exception& e) {
Logger::Error(e);
}
const std::string name = product->Name().get_value_or("");
const std::string guid = product->GlobalId();
gp_Trsf trsf;
try {
if (product->ObjectPlacement()) {
@@ -2554,7 +2554,7 @@ IfcGeom::BRepElement* IfcGeom::Kernel::create_brep_for_processed_representation(
return new BRepElement(
product->data().id(),
parent_id,
name,
name,
product_type,
guid,
context_string,
@@ -2706,10 +2706,10 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std
// is calculated later on when the layerset is applied.
reference_surface = new Geom_SurfaceOfLinearExtrusion(axis_curve, gp::DZ());
}
} else {
IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = IfcParse::traverse(body_representation)->as<IfcSchema::IfcExtrudedAreaSolid>();
if (extrusions->size() != 1) {
Logger::Message(Logger::LOG_WARNING, "No single extrusion found in body representation for:", product);
return false;
@@ -2753,7 +2753,7 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std
double thickness = (*it)->LayerThickness() * getValue(GV_LENGTH_UNIT);
thicknesses.push_back(thickness);
if (!positive) {
thickness *= -1;
}
@@ -2855,7 +2855,7 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
if (!axis_representation) {
return false;
}
IfcRepresentationShapeItems items;
{
Kernel temp = *this;
@@ -2870,10 +2870,10 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
b = TopoDS::Vertex(exp.Current());
if (a.IsNull()) {
a = b;
}
}
}
}
if (a.IsNull() || b.IsNull()) {
return false;
}
@@ -2891,7 +2891,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
*/
bool folds_made = false;
IfcSchema::IfcRelConnectsPathElements::list::ptr connections(new IfcSchema::IfcRelConnectsPathElements::list);
connections->push(wall->ConnectedFrom()->as<IfcSchema::IfcRelConnectsPathElements>());
connections->push( wall->ConnectedTo()->as<IfcSchema::IfcRelConnectsPathElements>());
@@ -2913,7 +2913,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
IfcSchema::IfcConnectionTypeEnum::Value other_type = connection->RelatedElement() == wall
? connection->RelatingConnectionType()
: connection->RelatedConnectionType();
if (other_type != IfcSchema::IfcConnectionTypeEnum::IfcConnectionType_ATPATH &&
if (other_type != IfcSchema::IfcConnectionTypeEnum::IfcConnectionType_ATPATH &&
(own_type == IfcSchema::IfcConnectionTypeEnum::IfcConnectionType_ATEND ||
own_type == IfcSchema::IfcConnectionTypeEnum::IfcConnectionType_ATSTART))
{
@@ -2929,7 +2929,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
if (endpoint_connections.size() == 0) {
return false;
}
// Count how many connections are made AT_START and AT_END respectively
int connection_type_count[2] = {0,0};
for (endpoint_connections_t::const_iterator it = endpoint_connections.begin(); it != endpoint_connections.end(); ++it) {
@@ -3055,7 +3055,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
Logger::Warning("Joined wall has no axis representation", other_wall);
continue;
}
IfcRepresentationShapeItems axis_items;
{
Kernel temp = *this;
@@ -3065,12 +3065,12 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
TopoDS_Shape axis_shape;
flatten_shape_list(axis_items, axis_shape, false);
// local and other are IfcLocalPlacements and therefore have a unit
// scale factor that can be applied by means of TopoDS_Shape::Move()
axis_shape.Move(other);
axis_shape.Move(local);
TopoDS_Shape body_shape;
flatten_shape_list(items, body_shape, false);
@@ -3080,7 +3080,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
// but it is assumed these are colinear.
Handle_Geom_Curve other_axis_curve;
double axis_u1, axis_u2;
{
{
TopExp_Explorer exp(axis_shape, TopAbs_EDGE);
if (!exp.More()) {
return false;
@@ -3109,10 +3109,10 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
if (u < axis_u1) axis_u1 = u;
if (u > axis_u2) axis_u2 = u;
}
}
}
}
}
double layer_offset = 0;
std::vector<double>::const_iterator thickness = thicknesses.begin();
@@ -3125,7 +3125,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
bool found_intersection = false, parallel = false;
boost::optional<gp_Pnt> point_outside_param_range;
const Handle_Geom_Surface& surface = *jt;
// Find the intersection point between the layerset surface
@@ -3170,7 +3170,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
Handle_Geom_Surface yz2 = new Geom_OffsetSurface(yz, 1.);
intersect(xy, yz2);
*/
Handle_Geom_Surface plane = new Geom_Plane(*point_outside_param_range, gp::DZ());
// vertical edges at wall end point face.
@@ -3234,7 +3234,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
// Convert parameter to point
gp_Pnt layer_fold_point;
layer_line->D0(dst.Parameter(), layer_fold_point);
GeomAPI_IntSS intersection4(body_surface, plane, 1.e-7);
if (intersection4.IsDone() && intersection4.NbLines() == 1) {
Handle_Geom_Curve body_trim_curve = intersection4.Line(1);
@@ -3250,9 +3250,9 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
}
}
}
}
}
}
@@ -3379,7 +3379,7 @@ namespace {
(s.ShapeType() == TopAbs_SHELL && k.split_solid_by_shell(i, s, a, b)))
{
slices.push_back(b);
i = a;
i = a;
} else {
return false;
}
@@ -3411,7 +3411,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
}
shells.Append(BRepBuilderAPI_MakeShell(surface, u1, v1, u2, v2).Shell());
} else {
faces_with_mass_t solids;
faces_with_mass_t solids;
for (folded_surfaces_t::value_type::const_iterator jt = it->begin(); jt != it->end(); ++jt) {
const Handle_Geom_Surface& surface = *jt;
double u1, v1, u2, v2;
@@ -3426,7 +3426,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
p2 = p.Translated(-n);
solids.push_back(std::make_pair(face, std::make_pair(p1, p2)));
}
if (solids.empty()) {
continue;
@@ -3454,7 +3454,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
for (faces_with_mass_t::const_iterator kt = solids.begin(); kt != solids.end(); ++kt) {
builder.Add(kt->first);
}
builder.Perform();
TopoDS_Shape s = builder.SewedShape();
if (s.ShapeType() == TopAbs_SHELL) {
@@ -3471,7 +3471,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
return false;
} else if (shells.Extent() == 1) {
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
TopoDS_Shape a,b;
if (split_solid_by_shell(it->Shape(), shells.First(), a, b)) {
@@ -3514,7 +3514,7 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
return false;
} else if (surfaces.size() == 3) {
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
TopoDS_Shape a,b;
if (split_solid_by_surface(it->Shape(), surfaces[1], a, b)) {
@@ -3537,7 +3537,7 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
BRepBndLib::Add(it->Shape(), bb);
}
double x1, y1, z1, x2, y2, z2;
double x1, y1, z1, x2, y2, z2;
bb.Get(x1, y1, z1, x2, y2, z2);
gp_Pnt p1(x1, y1, z1);
gp_Pnt p2(x2, y2, z2);
@@ -3546,18 +3546,18 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
ShapeAnalysis_Surface sas1(surfaces[0]);
ShapeAnalysis_Surface sas2(surfaces[1]);
const gp_Pnt2d uv = sas1.ValueOfUV(avg, 1e-3);
gp_Pnt ps1, ps2, mass;
gp_Vec du1, dv1, du2, dv2;
surfaces[0]->D1(uv.X(), uv.Y(), ps1, du1, dv1);
const gp_Vec n1 = dv1.XYZ() ^ du1.XYZ();
const bool reversed = gp_Dir(ps2.XYZ() - ps1.XYZ()).Dot(n1) < 0.;
surfaces[surfaces.size() - 1]->D0(uv.X(), uv.Y(), mass);
mass.ChangeCoord() += n1.XYZ();
*/
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
const TopoDS_Shape& s = it->Shape();
@@ -3634,7 +3634,7 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo
// Use a shell, typically one or more connected faces, that isolate part
// of the input shape, to split this shape into two parts. Make sure that
// the addition of the two result volumes matches that of the input.
TopoDS_Solid solid;
if (shell.ShapeType() == TopAbs_SHELL) {
solid = BRepBuilderAPI_MakeSolid(TopoDS::Shell(shell)).Solid();
@@ -3733,7 +3733,7 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
uv.SetX(d.Dot(pln->Position().XDirection()));
uv.SetY(d.Dot(pln->Position().YDirection()));
}
if (uv.X() < u1) u1 = uv.X();
if (uv.Y() < v1) v1 = uv.Y();
if (uv.X() > u2) u2 = uv.X();
@@ -3776,7 +3776,7 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
}
delete sas;
delete sas;
return vertex_count > 0;
}
@@ -3853,7 +3853,7 @@ bool IfcGeom::Kernel::approximate_plane_through_wire(const TopoDS_Wire& wire, gp
gp_Pnt current, previous, first;
gp_XYZ center;
int n = 0;
BRepTools_WireExplorer exp(wire);
for (;; exp.Next()) {
@@ -3888,7 +3888,7 @@ bool IfcGeom::Kernel::approximate_plane_through_wire(const TopoDS_Wire& wire, gp
if (n < 3) {
return false;
}
plane = gp_Pln(center / n, gp_Dir(x, y, z));
exp.Init(wire);
@@ -3925,17 +3925,17 @@ bool IfcGeom::Kernel::flatten_wire(TopoDS_Wire& wire) {
}
bool IfcGeom::Kernel::triangulate_wire(const std::vector<TopoDS_Wire>& wires, TopTools_ListOfShape& faces) {
// This is a bit of a precarious approach, but seems to work for the
// versions of OCCT tested for. OCCT has a Delaunay triangulation function
// BRepMesh_Delaun, but it is notoriously hard to interpret the results
// (due to the Bowyer-Watson super triangle perhaps?). Therefore
// alternatively we use the regular OCCT incremental mesher on a new face
// created from the UV coordinates of the original wire. Pray to our gods
// that the vertex coordinates are unaffected by the meshing algorithm and
// This is a bit of a precarious approach, but seems to work for the
// versions of OCCT tested for. OCCT has a Delaunay triangulation function
// BRepMesh_Delaun, but it is notoriously hard to interpret the results
// (due to the Bowyer-Watson super triangle perhaps?). Therefore
// alternatively we use the regular OCCT incremental mesher on a new face
// created from the UV coordinates of the original wire. Pray to our gods
// that the vertex coordinates are unaffected by the meshing algorithm and
// map them back to 3d coordinates when iterating over the mesh triangles.
// In addition, to maintain a manifold shell, we need to make sure that
// every edge from the input wire is used exactly once in the list of
// In addition, to maintain a manifold shell, we need to make sure that
// every edge from the input wire is used exactly once in the list of
// resulting faces. And that other internal edges are used twice.
typedef std::pair<double, double> uv_node;
@@ -3995,7 +3995,7 @@ bool IfcGeom::Kernel::triangulate_wire(const std::vector<TopoDS_Wire>& wires, To
// @todo is this necessary?
TopoDS_Face f = mf->Face();
mf->Init(f);
}
}
mf->Add(mp.Wire());
} else {
mf.reset(new BRepBuilderAPI_MakeFace(mp.Wire()));
@@ -4007,22 +4007,22 @@ bool IfcGeom::Kernel::triangulate_wire(const std::vector<TopoDS_Wire>& wires, To
// Create a triangular mesh from the face
BRepMesh_IncrementalMesh(face, Precision::Confusion());
int n123[3];
int n123[3];
TopLoc_Location loc;
Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc);
if (!tri.IsNull()) {
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for (int i = 1; i <= triangles.Length(); ++i) {
for (int i = 1; i <= triangles.Length(); ++i) {
if (face.Orientation() == TopAbs_REVERSED)
triangles(i).Get(n123[2], n123[1], n123[0]);
else triangles(i).Get(n123[0], n123[1], n123[2]);
// Create polygons from the mesh vertices
BRepBuilderAPI_MakeWire mp2;
for (int j = 0; j < 3; ++j) {
uv_node uvnodes[2];
TopoDS_Vertex vs[2];
@@ -4224,13 +4224,13 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
throw geometry_exception("Invalid loop");
}
bool intersected = false;
// tfk: Extrema on infinite curves proved to be more robust.
// TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face();
// ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION));
double eps = 0;
if (getValue(GV_NO_WIRE_INTERSECTION_TOLERANCE) < 0.) {
eps = faceset_helper_
@@ -4262,11 +4262,11 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
if ((std::max)(i, j) - (std::min)(i, j) <= 1) {
continue;
}
}
}
// Only check non-consecutive edges
if (i == n - 1 && j == 0) continue;
double u11, u12, u21, u22, U1, U2;
GeomAPI_ExtremaCurveCurve ecc(
BRep_Tool::Curve(wd->Edge(i + 1), u11, u12),
@@ -4370,7 +4370,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
}
void IfcGeom::Kernel::select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest) {
double mass = 0.;
double mass = 0.;
TopTools_ListIteratorOfListOfShape it(shapes);
for (; it.More(); it.Next()) {
/*
@@ -4393,7 +4393,7 @@ void IfcGeom::Kernel::select_largest(const TopTools_ListOfShape& shapes, TopoDS_
}
if (Precision::IsInfinite(xyz_max[i])) {
xyz_max[i] = 0.;
}
}
m *= (xyz_max[i] + eps) - (xyz_min[i] - eps);
}
@@ -4456,7 +4456,7 @@ bool IfcGeom::Kernel::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b
for (int j = 0; j < 2; ++j) {
for (int k = 0; k < 2; ++k) {
gp_Pnt p(xs[i], ys[j], zs[k]);
gp_Vec d = p.XYZ() - P.XYZ();
const double u = d.Dot(x);
const double v = d.Dot(y);
@@ -4496,7 +4496,7 @@ bool IfcGeom::Kernel::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b
BRepPrimAPI_MakePrism mp(mf.Face(), vec);
box = mp.Shape();
height = D;
return true;
}
@@ -4671,7 +4671,7 @@ namespace {
// Edge curves belonging to different operands intersect, don't process
// using builder.
Logger::Notice("Intersecting boundaries");
return false;
return false;
}
}
}
@@ -4689,14 +4689,14 @@ namespace {
std::vector<BRepTopAdaptor_FClass2d> wire_clss;
wire_clss.reserve(wires.size());
std::vector<ShapeAnalysis_Surface> sass;
std::vector<std::unique_ptr<ShapeAnalysis_Surface>> sass;
sass.reserve(wires.size());
for (auto& w : wires) {
wire_faces.push_back(BRepBuilderAPI_MakeFace(w).Face());
wire_clss.emplace_back(wire_faces.back(), eps);
sass.emplace_back(BRep_Tool::Surface(wire_faces.back()));
}
sass.push_back(std::make_unique<ShapeAnalysis_Surface>(BRep_Tool::Surface(wire_faces.back())));
}
// First check for containment in outer wire
for (auto it = ++wires.begin(); it != wires.end(); ++it) {
@@ -4709,7 +4709,7 @@ namespace {
auto& v = TopoDS::Vertex(it_v.Value());
auto pnt = BRep_Tool::Pnt(v);
auto p2d = sass[0].ValueOfUV(pnt, eps);
auto p2d = sass[0]->ValueOfUV(pnt, eps);
if (wire_clss[0].Perform(p2d) != TopAbs_IN) {
// A wire is not contained in the outer wire, it's a subtraction without
// any effect and marked as redundant. Feeding it to the builder algo
@@ -4751,7 +4751,7 @@ namespace {
auto& v = TopoDS::Vertex(it_v.Value());
auto pnt = BRep_Tool::Pnt(v);
auto p2d = sass[wire_index].ValueOfUV(pnt, eps);
auto p2d = sass[wire_index]->ValueOfUV(pnt, eps);
if (wire_clss[wire_index].Perform(p2d) == TopAbs_IN) {
// A wire is contained within another operand
redundant[other_index] = true;
@@ -4969,7 +4969,7 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo
if (!boolean_op_2d_success) {
PERF("boolean operation: 2d");
// Retry using generic 2d using boolean algo on faces
boolean_op_2d_success = boolean_operation(a_face, b_faces, op, face_result, fuzziness);
}
@@ -5192,11 +5192,11 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo
success = false;
Logger::Notice("Boolean result discarded because subtractions results in only the addition of faces");
} else {
// when there are edges or vertex-edge distances close to the used fuzziness, the
// when there are edges or vertex-edge distances close to the used fuzziness, the
// output is not trusted and the operation is attempted with a higher fuzziness.
int reason = 0;
double v;
{
PERF("boolean operation: result min edge length check");
@@ -5207,7 +5207,7 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo
goto skip_further_checks;
}
}
{
PERF("boolean operation: result min vertex-edge dist check");
@@ -5218,7 +5218,7 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a_input, const TopTo
goto skip_further_checks;
}
}
{
PERF("boolean operation: result min face-face dist check");
@@ -5336,7 +5336,7 @@ bool IfcGeom::Kernel::faceset_helper<CP, LP>::construct(const std::vector<double
template <typename CP, typename LP>
IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(Kernel* kernel, const IfcSchema::IfcConnectedFaceSet* l)
: kernel_(kernel)
: kernel_(kernel)
, non_manifold_(false)
{
kernel->faceset_helper_ = this;
@@ -5359,7 +5359,7 @@ IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(Kernel* kernel, const If
box.Add(*p);
} else {
delete p;
}
}
}
// Use the bbox diagonal to influence local epsilon
@@ -5414,7 +5414,7 @@ IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(Kernel* kernel, const If
// occt uses some hard coded precision values, don't go smaller than that.
// @todo, can be reset though with BRepLib::Precision(double)
eps_ = Precision::Confusion();
}
}
for (int pnt_i = 0; pnt_i < (int)pnts.size(); ++pnt_i) {
if (pnts[pnt_i]) {
@@ -5427,7 +5427,7 @@ IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(Kernel* kernel, const If
vertex_mapping_.insert({ get_idx(pt), pnt_i });
}
}
}
}
typedef std::array<int, 2> edge_t;
typedef std::set<edge_t> edge_set_t;
@@ -5474,7 +5474,7 @@ IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(Kernel* kernel, const If
if (p.second != 2) {
non_manifold += 1;
}
}
}
if (loops_removed || (non_manifold && l->declaration().is(IfcSchema::IfcClosedShell::Class()))) {
@@ -5640,4 +5640,4 @@ IfcGeom::Kernel::faceset_helper<CP, LP>::faceset_helper(
}
template class IfcGeom::Kernel::faceset_helper<const IfcSchema::IfcCartesianPoint*, const IfcSchema::IfcPolyLoop*>;
template class IfcGeom::Kernel::faceset_helper<std::vector<double>, std::vector<int>>;
template class IfcGeom::Kernel::faceset_helper<std::vector<double>, std::vector<int>>;