/*static*/ BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms) { BaseGeomPtrVector result; std::vector<bool> used(geoms.size(),false); if (geoms.empty()) { return result; } if (geoms.size() == 1) { //don't bother for single geom (circles, ellipses,etc) result.push_back(geoms[0]); } else { //start with first edge result.push_back(geoms[0]); Base::Vector2d atPoint = (geoms[0])->getEndPoint(); used[0] = true; for (unsigned int i = 1; i < geoms.size(); i++) { //do size-1 more edges auto next( nextGeom(atPoint, geoms, used, Precision::Confusion()) ); if (next.index) { //found an unused edge with vertex == atPoint BaseGeom* nextEdge = geoms.at(next.index); used[next.index] = true; nextEdge->reversed = next.reversed; result.push_back(nextEdge); if (next.reversed) { atPoint = nextEdge->getStartPoint(); } else { atPoint = nextEdge->getEndPoint(); } } else { Base::Console().Log("Error - Geometry::chainGeoms - couldn't find next edge\n"); //TARFU } } } return result; }
//! update edgeGeom and vertexGeom from Compound of edges void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible) { if(edgeCompound.IsNull()) { Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n"); return; // There is no OpenCascade Geometry to be calculated } BaseGeom* base; TopExp_Explorer edges(edgeCompound, TopAbs_EDGE); for (int i = 1 ; edges.More(); edges.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); if (edge.IsNull()) { //Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); continue; } if (DrawUtil::isZeroEdge(edge)) { Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i); continue; } base = BaseGeom::baseFactory(edge); if (base == nullptr) { Base::Console().Message("Error - GO::addGeomFromCompound - baseFactory failed for edge: %d\n",i); throw Base::Exception("GeometryObject::addGeomFromCompound - baseFactory failed"); } base->classOfEdge = category; base->visible = visible; edgeGeom.push_back(base); //add vertices of new edge if not already in list if (visible) { BaseGeom* lastAdded = edgeGeom.back(); bool v1Add = true, v2Add = true; bool c1Add = true; TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint()); TechDrawGeometry::Circle* circle = dynamic_cast<TechDrawGeometry::Circle*>(lastAdded); TechDrawGeometry::Vertex* c1 = nullptr; if (circle) { c1 = new TechDrawGeometry::Vertex(circle->center); c1->isCenter = true; c1->visible = true; } std::vector<Vertex *>::iterator itVertex = vertexGeom.begin(); for (; itVertex != vertexGeom.end(); itVertex++) { if ((*itVertex)->isEqual(v1,Precision::Confusion())) { v1Add = false; } if ((*itVertex)->isEqual(v2,Precision::Confusion())) { v2Add = false; } if (circle) { if ((*itVertex)->isEqual(c1,Precision::Confusion())) { c1Add = false; } } } if (v1Add) { vertexGeom.push_back(v1); v1->visible = true; } else { delete v1; } if (v2Add) { vertexGeom.push_back(v2); v2->visible = true; } else { delete v2; } if (circle) { if (c1Add) { vertexGeom.push_back(c1); c1->visible = true; } else { delete c1; } } } } //end TopExp }
//! update edgeGeom and vertexGeom from Compound of edges void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible) { if(edgeCompound.IsNull()) { Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n"); return; // There is no OpenCascade Geometry to be calculated } // build a mesh to explore the shape //BRepMesh_IncrementalMesh(edgeCompound, Tolerance); //TODO: is this needed? no idea why we need to mesh shape doesn't seem to change anything // Explore all edges of edgeCompound and calculate base geometry representation BaseGeom* base; TopExp_Explorer edges(edgeCompound, TopAbs_EDGE); for (int i = 1 ; edges.More(); edges.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); if (edge.IsNull()) { Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); continue; } base = BaseGeom::baseFactory(edge); base->classOfEdge = category; base->visible = visible; edgeGeom.push_back(base); //add vertices of new edge if not already in list if (visible) { BaseGeom* lastAdded = edgeGeom.back(); //if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? baseFactory always returns a Base?) bool v1Add = true, v2Add = true; bool c1Add = true; TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint()); TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint()); TechDrawGeometry::Circle* circle = dynamic_cast<TechDrawGeometry::Circle*>(lastAdded); TechDrawGeometry::Vertex* c1 = nullptr; if (circle) { c1 = new TechDrawGeometry::Vertex(circle->center); c1->isCenter = true; c1->visible = true; } std::vector<Vertex *>::iterator itVertex = vertexGeom.begin(); for (; itVertex != vertexGeom.end(); itVertex++) { if ((*itVertex)->isEqual(v1,Precision::Confusion())) { v1Add = false; } if ((*itVertex)->isEqual(v2,Precision::Confusion())) { v2Add = false; } if (circle) { if ((*itVertex)->isEqual(c1,Precision::Confusion())) { c1Add = false; } } } if (v1Add) { vertexGeom.push_back(v1); v1->visible = true; } else { delete v1; } if (v2Add) { vertexGeom.push_back(v2); v2->visible = true; } else { delete v2; } if (circle) { if (c1Add) { vertexGeom.push_back(c1); c1->visible = true; } else { delete c1; } } } } }