bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& result) { IfcSchema::IfcOrientedEdge::list::ptr li = l->EdgeList(); BRepBuilderAPI_MakeWire mw; for (IfcSchema::IfcOrientedEdge::list::it it = li->begin(); it != li->end(); ++it) { IfcSchema::IfcOrientedEdge* e = *it; IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) e->EdgeStart())->VertexGeometry(); IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) e->EdgeEnd())->VertexGeometry(); if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity); return false; } gp_Pnt p1, p2; if (!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) || !IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2)) { return false; } mw.Add(BRepBuilderAPI_MakeEdge(p1, p2)); continue; IfcSchema::IfcEdge* base = e->EdgeElement(); TopoDS_Wire w; if (convert_wire(e->EdgeElement(), w)) { if (!e->Orientation()) w.Reverse(); mw.Add(w); } } result = mw; return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shape& face) { const double r = l->Radius() * getValue(GV_LENGTH_UNIT); const double t = l->WallThickness() * getValue(GV_LENGTH_UNIT); if ( r == 0.0f || t == 0.0f ) { Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); return false; } gp_Trsf2d trsf2d; bool has_position = true; #ifdef USE_IFC4 has_position = l->hasPosition(); #endif if (has_position) { IfcGeom::Kernel::convert(l->Position(), trsf2d); } gp_Ax2 ax = gp_Ax2().Transformed(trsf2d); BRepBuilderAPI_MakeWire outer; Handle(Geom_Circle) outerCircle = new Geom_Circle(ax, r); outer.Add(BRepBuilderAPI_MakeEdge(outerCircle)); BRepBuilderAPI_MakeFace mf(outer.Wire(), false); BRepBuilderAPI_MakeWire inner; Handle(Geom_Circle) innerCirlce = new Geom_Circle(ax, r-t); inner.Add(BRepBuilderAPI_MakeEdge(innerCirlce)); mf.Add(inner); ShapeFix_Shape sfs(mf.Face()); sfs.Perform(); face = TopoDS::Face(sfs.Shape()); return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) { IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry(); IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry(); if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity); return false; } gp_Pnt p1, p2; if (!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) || !IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2)) { return false; } BRepBuilderAPI_MakeWire mw; Handle_Geom_Curve crv; // The lack of a clear separation between topological and geometrical entities // is starting to get problematic. If the underlying curve is bounded it is // assumed that a topological wire can be crafted from it. After which an // attempt is made to reconstruct it from the individual curves and the vertices // of the IfcEdgeCurve. const bool is_bounded = l->EdgeGeometry()->is(IfcSchema::Type::IfcBoundedCurve); if (!is_bounded && convert_curve(l->EdgeGeometry(), crv)) { mw.Add(BRepBuilderAPI_MakeEdge(crv, p1, p2)); result = mw; return true; } else if (is_bounded && convert_wire(l->EdgeGeometry(), result)) { if (!l->SameSense()) std::swap(pnt1, pnt2); TopExp_Explorer exp(result, TopAbs_EDGE); bool first = true; while (exp.More()) { const TopoDS_Edge& ed = TopoDS::Edge(exp.Current()); Standard_Real u1, u2; Handle(Geom_Curve) ecrv = BRep_Tool::Curve(ed, u1, u2); exp.Next(); const bool last = !exp.More(); first = false; if (first && last) { mw.Add(BRepBuilderAPI_MakeEdge(ecrv, p1, p2)); } else if (first) { gp_Pnt pu; ecrv->D0(u2, pu); mw.Add(BRepBuilderAPI_MakeEdge(ecrv, p1, pu)); } else if (last) { gp_Pnt pu; ecrv->D0(u1, pu); mw.Add(BRepBuilderAPI_MakeEdge(ecrv, pu, p2)); } else { mw.Add(BRepBuilderAPI_MakeEdge(ecrv, u1, u2)); } } result = mw; return true; } else { return false; } }
void CrossSection::connectEdges (const std::list<TopoDS_Edge>& edges, std::list<TopoDS_Wire>& wires) const { std::list<TopoDS_Edge> edge_list = edges; while (edge_list.size() > 0) { BRepBuilderAPI_MakeWire mkWire; // add and erase first edge mkWire.Add(edge_list.front()); edge_list.erase(edge_list.begin()); TopoDS_Wire new_wire = mkWire.Wire(); // current new wire // try to connect each edge to the wire, the wire is complete if no more egdes are connectible bool found = false; do { found = false; for (std::list<TopoDS_Edge>::iterator pE = edge_list.begin(); pE != edge_list.end();++pE) { mkWire.Add(*pE); if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) { // edge added ==> remove it from list found = true; edge_list.erase(pE); new_wire = mkWire.Wire(); break; } } } while (found); wires.push_back(new_wire); } }
TopoDS_Shape OCCPartFactory::makeCube( const Standard_Real width, const Standard_Real height, const Standard_Real depth) { // define points gp_Pnt pt1( -width / 2.0, 0.0, 0.0 ); gp_Pnt pt2( -width / 2.0, -depth / 2.0, 0.0 ); gp_Pnt pt3( width / 2.0, -depth / 2.0, 0.0 ); gp_Pnt pt4( width /2.0, 0.0, 0.0 ); // define segments Handle_Geom_TrimmedCurve seg1 = GC_MakeSegment( pt1, pt2 ); Handle_Geom_TrimmedCurve seg2 = GC_MakeSegment( pt2, pt3 ); Handle_Geom_TrimmedCurve seg3 = GC_MakeSegment( pt3, pt4 ); // make edge TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge( seg1 ); TopoDS_Edge edge2 = BRepBuilderAPI_MakeEdge( seg2 ); TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge( seg3 ); // make wire TopoDS_Wire wire1 = BRepBuilderAPI_MakeWire( edge1, edge2, edge3 ); //Complete Profile gp_Ax1 xAxis = gp::OX(); gp_Trsf transfer; transfer.SetMirror( xAxis ); BRepBuilderAPI_Transform aBRepTrsf( wire1 , transfer ); TopoDS_Shape mirroredShape = aBRepTrsf.Shape(); TopoDS_Wire mirroredWire1 = TopoDS::Wire( mirroredShape ); BRepBuilderAPI_MakeWire mkWire; mkWire.Add( wire1 ); mkWire.Add( mirroredWire1 ); TopoDS_Wire wireProfile = mkWire.Wire(); //Body : Prism the Profile TopoDS_Face faceProfile = BRepBuilderAPI_MakeFace( wireProfile ); gp_Vec prismVec( 0.0 , 0.0 , height ); TopoDS_Shape cube = BRepPrimAPI_MakePrism( faceProfile, prismVec); // cube.setMaterial( Graphic3d_NOM_JADE ); // Handle_AIS_Shape shape = new AIS_Shape( cube ); // shape->SetColor( Quantity_NOC_RED ); // return shape; return cube; }
TopoDS_Wire CCPACSWingProfile::GetWire() { Update(); // rebuild closed wire BRepBuilderAPI_MakeWire closedWireBuilder; closedWireBuilder.Add(profileAlgo->GetUpperLowerWire()); if (!profileAlgo->GetTrailingEdge().IsNull()) { closedWireBuilder.Add(profileAlgo->GetTrailingEdge()); } return closedWireBuilder.Wire(); }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape& face) { const double d = l->Thickness() * getValue(GV_LENGTH_UNIT) / 2.; TopoDS_Wire wire; if (!convert_wire(l->Curve(), wire)) return false; // BRepOffsetAPI_MakeOffset insists on creating circular arc // segments for joining the curves that constitute the center // line. This is probably not in accordance with the IFC spec. // Although it does not specify a method to join segments // explicitly, it does dictate 'a constant thickness along the // curve'. Therefore for simple singular wires a quick // alternative is provided that uses a straight join. TopExp_Explorer exp(wire, TopAbs_EDGE); TopoDS_Edge edge = TopoDS::Edge(exp.Current()); exp.Next(); if (!exp.More()) { double u1, u2; Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2); Handle(Geom_TrimmedCurve) trim = new Geom_TrimmedCurve(curve, u1, u2); Handle(Geom_OffsetCurve) c1 = new Geom_OffsetCurve(trim, d, gp::DZ()); Handle(Geom_OffsetCurve) c2 = new Geom_OffsetCurve(trim, -d, gp::DZ()); gp_Pnt c1a, c1b, c2a, c2b; c1->D0(c1->FirstParameter(), c1a); c1->D0(c1->LastParameter(), c1b); c2->D0(c2->FirstParameter(), c2a); c2->D0(c2->LastParameter(), c2b); BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(c1)); mw.Add(BRepBuilderAPI_MakeEdge(c1a, c2a)); mw.Add(BRepBuilderAPI_MakeEdge(c2)); mw.Add(BRepBuilderAPI_MakeEdge(c2b, c1b)); face = BRepBuilderAPI_MakeFace(mw.Wire()); } else { BRepOffsetAPI_MakeOffset offset(BRepBuilderAPI_MakeFace(gp_Pln(gp::Origin(), gp::DZ()))); offset.AddWire(wire); offset.Perform(d); face = BRepBuilderAPI_MakeFace(TopoDS::Wire(offset)); } return true; }
//! make a clean wire with sorted, oriented, connected, etc edges TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol) { TopoDS_Wire result; BRepBuilderAPI_MakeWire mkWire; ShapeFix_ShapeTolerance sTol; Handle(ShapeExtend_WireData) wireData = new ShapeExtend_WireData(); for (auto e:edges) { wireData->Add(e); } Handle(ShapeFix_Wire) fixer = new ShapeFix_Wire; fixer->Load(wireData); fixer->Perform(); fixer->FixReorder(); fixer->SetMaxTolerance(tol); fixer->ClosedWireMode() = Standard_True; fixer->FixConnected(Precision::Confusion()); fixer->FixClosed(Precision::Confusion()); for (int i = 1; i <= wireData->NbEdges(); i ++) { TopoDS_Edge edge = fixer->WireData()->Edge(i); sTol.SetTolerance(edge, tol, TopAbs_VERTEX); mkWire.Add(edge); } result = mkWire.Wire(); return result; }
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const { const App::DocumentObject* path = sel.getObject(); if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return false; const std::vector<std::string>& sub = sel.getSubNames(); TopoDS_Shape pathShape; const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue(); if (!sub.empty()) { try { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } pathShape = mkWire.Wire(); } catch (...) { return false; } } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { pathShape = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); pathShape = mkWire.Wire(); } return (!pathShape.IsNull()); }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleProfileDef* l, TopoDS_Shape& face) { const double r = l->Radius() * getValue(GV_LENGTH_UNIT); if ( r == 0.0f ) { Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); return false; } gp_Trsf2d trsf2d; bool has_position = true; #ifdef USE_IFC4 has_position = l->hasPosition(); #endif if (has_position) { IfcGeom::Kernel::convert(l->Position(), trsf2d); } gp_Ax2 ax = gp_Ax2().Transformed(trsf2d); Handle(Geom_Circle) circle = new Geom_Circle(ax, r); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle); BRepBuilderAPI_MakeWire w; w.Add(edge); TopoDS_Face f; bool success = convert_wire_to_face(w, f); if (success) face = f; return success; }
void BRepOffsetAPI_MakeOffsetFix::AddWire(const TopoDS_Wire& Spine) { TopoDS_Wire wire = Spine; int numEdges = 0; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { numEdges++; xp.Next(); } if (numEdges == 1) { TopLoc_Location edgeLocation; BRepBuilderAPI_MakeWire mkWire; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { // The trick is to reset the placement of an edge before // passing it to BRepOffsetAPI_MakeOffset because then it // will create the expected result. // Afterwards apply the placement again on the result shape. // See the method MakeWire() TopoDS_Edge edge = TopoDS::Edge(xp.Current()); edgeLocation = edge.Location(); edge.Location(TopLoc_Location()); mkWire.Add(edge); myLocations.push_back(std::make_pair(edge, edgeLocation)); xp.Next(); } wire = mkWire.Wire(); } mkOffset.AddWire(wire); myResult.Nullify(); }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_Shape& face) { double rx = l->SemiAxis1() * getValue(GV_LENGTH_UNIT); double ry = l->SemiAxis2() * getValue(GV_LENGTH_UNIT); if ( rx < ALMOST_ZERO || ry < ALMOST_ZERO ) { Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); return false; } const bool rotated = ry > rx; gp_Trsf2d trsf; convert(l->Position(),trsf); gp_Ax2 ax = gp_Ax2(); if (rotated) { ax.Rotate(ax.Axis(), M_PI / 2.); std::swap(rx, ry); } ax.Transform(trsf); BRepBuilderAPI_MakeWire w; Handle(Geom_Ellipse) ellipse = new Geom_Ellipse(ax, rx, ry); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ellipse); w.Add(edge); TopoDS_Face f; bool success = convert_wire_to_face(w, f); if (success) face = f; return success; }
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) { 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); vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(),xy.Y(),0.0f)); } BRepBuilderAPI_MakeWire w; for ( int i = 0; i < numVerts; i ++ ) w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts])); IfcGeom::convert_wire_to_face(w.Wire(),face); if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > 1e-7 ) { BRepFilletAPI_MakeFillet2d fillet (face); for ( int i = 0; i < numFillets; i ++ ) { const double radius = filletRadii[i]; if ( radius <= 1e-7 ) continue; fillet.AddFillet(vertices[filletIndices[i]],radius); } fillet.Build(); if (fillet.IsDone()) { face = TopoDS::Face(fillet.Shape()); } else { Logger::Message(Logger::LOG_WARNING, "Failed to process profile fillets"); } } delete[] vertices; return true; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdge* l, TopoDS_Wire& result) { if (!l->EdgeStart()->is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->is(IfcSchema::Type::IfcVertexPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l->entity); return false; } IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry(); IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry(); if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) { Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity); return false; } gp_Pnt p1, p2; if (!convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) || !convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2)) { return false; } BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(p1, p2)); result = mw.Wire(); return true; }
void BRepOffsetAPI_MakeOffsetFix::MakeWire(TopoDS_Shape& wire) { // get the edges of the wire and check which of the stored edges // serve as input of the wire TopTools_MapOfShape aMap; TopExp_Explorer xp(wire, TopAbs_EDGE); while (xp.More()) { aMap.Add(xp.Current()); xp.Next(); } std::list<TopoDS_Edge> edgeList; for (auto itLoc : myLocations) { const TopTools_ListOfShape& newShapes = mkOffset.Generated(itLoc.first); for (TopTools_ListIteratorOfListOfShape it(newShapes); it.More(); it.Next()) { TopoDS_Shape newShape = it.Value(); if (aMap.Contains(newShape)) { newShape.Move(itLoc.second); edgeList.push_back(TopoDS::Edge(newShape)); } } } if (!edgeList.empty()) { BRepBuilderAPI_MakeWire mkWire; mkWire.Add(edgeList.front()); edgeList.pop_front(); wire = mkWire.Wire(); bool found = false; do { found = false; for (std::list<TopoDS_Edge>::iterator pE = edgeList.begin(); pE != edgeList.end(); ++pE) { mkWire.Add(*pE); if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) { // edge added ==> remove it from list found = true; edgeList.erase(pE); wire = mkWire.Wire(); break; } } } while (found); } }
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const { const App::DocumentObject* path = sel.getObject(); if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return false; const std::vector<std::string>& sub = sel.getSubNames(); TopoDS_Shape pathShape; const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue(); if (!sub.empty()) { try { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } pathShape = mkWire.Wire(); } catch (...) { return false; } } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { pathShape = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); pathShape = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { try { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { return false; } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) return false; pathShape = hWires->Value(1); } catch (...) { return false; } } return (!pathShape.IsNull()); }
// Returns the wing profile lower and upper wire fused TopoDS_Wire CCPACSWingProfile::GetSplitWire() { Update(); // rebuild closed wire BRepBuilderAPI_MakeWire closedWireBuilder; closedWireBuilder.Add(profileAlgo->GetLowerWire()); closedWireBuilder.Add(profileAlgo->GetUpperWire()); if (!profileAlgo->GetTrailingEdge().IsNull()) { closedWireBuilder.Add(profileAlgo->GetTrailingEdge()); } closedWireBuilder.Build(); if (!closedWireBuilder.IsDone()) { throw CTiglError("Error creating closed wing profile"); } return closedWireBuilder.Wire(); }
void Pipe::buildPipePath(const Part::TopoShape& shape, const std::vector< std::string >& subedge, TopoDS_Shape& path) { if (!shape._Shape.IsNull()) { try { if (!subedge.empty()) { //if(SpineTangent.getValue()) //getContiniusEdges(shape, subedge); BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if (it.Value().IsNull()) throw Base::Exception("In valid element in spine."); if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { throw Base::Exception("Element in spine is neither an edge nor a wire."); } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) throw Base::Exception("Spine is not connected."); path = hWires->Value(1); } else { throw Base::Exception("Spine is neither an edge nor a wire."); } } catch (Standard_Failure) { throw Base::Exception("Invalid spine."); } } }
bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr l, TopoDS_Wire& result) { Ifc2x3::IfcCartesianPoint::list points = l->Polygon(); BRepBuilderAPI_MakeWire w; gp_Pnt P1;gp_Pnt P2;gp_Pnt F; int count = 0; for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) { IfcGeom::convert(*it,P2); if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) { w.Add(BRepBuilderAPI_MakeEdge(P1,P2)); count ++; } else if ( ! count ) F = P2; P1 = P2; } if ( !P1.IsEqual(F,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) { w.Add(BRepBuilderAPI_MakeEdge(P1,F)); count ++; } if ( count < 3 ) return false; result = w.Wire(); return true; }
// Make a TopoDS_Wire from a list of TopoDS_Edges TopoDS_Wire edgesToWire(std::vector<TopoDS_Edge> Edges) { TopoDS_Wire occwire; std::vector<TopoDS_Edge>::iterator iEdge; BRepBuilderAPI_MakeWire mkWire; for (iEdge = Edges.begin(); iEdge != Edges.end(); ++iEdge){ mkWire.Add(*iEdge); if (!mkWire.IsDone()) { Base::Console().Message("FT2FC Trace edgesToWire failed to add wire\n"); } } occwire = mkWire.Wire(); BRepLib::BuildCurves3d(occwire); return(occwire); }
bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr l, TopoDS_Wire& result) { Ifc2x3::IfcCartesianPoint::list points = l->Points(); BRepBuilderAPI_MakeWire w; gp_Pnt P1;gp_Pnt P2; for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) { IfcGeom::convert(*it,P2); if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) w.Add(BRepBuilderAPI_MakeEdge(P1,P2)); P1 = P2; } result = w.Wire(); return true; }
int OCCWire::createWire(std::vector<OCCEdge *> edges) { try { BRepBuilderAPI_MakeWire MW; for (unsigned i=0; i<edges.size(); i++) { OCCEdge *edge = edges[i]; MW.Add(edge->getEdge()); } BRepBuilderAPI_WireError error = MW.Error(); switch (error) { case BRepBuilderAPI_EmptyWire: { StdFail_NotDone::Raise("Wire empty"); break; } case BRepBuilderAPI_DisconnectedWire: { StdFail_NotDone::Raise("Disconnected wire"); break; } case BRepBuilderAPI_NonManifoldWire : { StdFail_NotDone::Raise("non-manifold wire"); break; } } this->setShape(MW.Wire()); // possible fix shape if (!this->fixShape()) StdFail_NotDone::Raise("Shapes not valid"); } catch(Standard_Failure &err) { Handle_Standard_Failure e = Standard_Failure::Caught(); const Standard_CString msg = e->GetMessageString(); if (msg != NULL && strlen(msg) > 1) { setErrorMessage(msg); } else { setErrorMessage("Failed to create wire"); } return 0; } return 1; }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSubedge* l, TopoDS_Wire& result) { TopoDS_Wire temp; if (convert_wire(l->ParentEdge(), result) && convert((IfcSchema::IfcEdge*) l, temp)) { TopExp_Explorer exp(result, TopAbs_EDGE); TopoDS_Edge edge = TopoDS::Edge(exp.Current()); Standard_Real u1, u2; Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u1, u2); TopoDS_Vertex v1, v2; TopExp::Vertices(temp, v1, v2); BRepBuilderAPI_MakeWire mw; mw.Add(BRepBuilderAPI_MakeEdge(crv, v1, v2)); result = mw.Wire(); return true; } else { return false; } }
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& result) { IfcSchema::IfcOrientedEdge::list::ptr li = l->EdgeList(); BRepBuilderAPI_MakeWire mw; for (IfcSchema::IfcOrientedEdge::list::it it = li->begin(); it != li->end(); ++it) { TopoDS_Wire w; if (convert_wire(*it, w)) { if (!(*it)->Orientation()) w.Reverse(); TopoDS_Iterator topoit(w, false); for (; topoit.More(); topoit.Next()) { const TopoDS_Edge& e = TopoDS::Edge(topoit.Value()); mw.Add(e); } // mw.Add(w); } } result = mw; return true; }
App::DocumentObjectExecReturn *Torus::execute(void) { if (Radius1.getValue() < Precision::Confusion()) return new App::DocumentObjectExecReturn("Radius of torus too small"); if (Radius2.getValue() < Precision::Confusion()) return new App::DocumentObjectExecReturn("Radius of torus too small"); try { #if 1 // Build a torus gp_Circ circle; circle.SetRadius(Radius2.getValue()); gp_Pnt pos(Radius1.getValue(),0,0); gp_Dir dir(0,1,0); circle.SetAxis(gp_Ax1(pos, dir)); BRepBuilderAPI_MakeEdge mkEdge(circle, Base::toRadians<double>(Angle1.getValue()+180.0f), Base::toRadians<double>(Angle2.getValue()+180.0f)); BRepBuilderAPI_MakeWire mkWire; mkWire.Add(mkEdge.Edge()); BRepBuilderAPI_MakeFace mkFace(mkWire.Wire()); BRepPrimAPI_MakeRevol mkRevol(mkFace.Face(), gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1)), Base::toRadians<double>(Angle3.getValue()), Standard_True); TopoDS_Shape ResultShape = mkRevol.Shape(); #else BRepPrimAPI_MakeTorus mkTorus(Radius1.getValue(), Radius2.getValue(), Angle1.getValue()/180.0f*Standard_PI, Angle2.getValue()/180.0f*Standard_PI, Angle3.getValue()/180.0f*Standard_PI); const TopoDS_Solid& ResultShape = mkTorus.Solid(); #endif this->Shape.setValue(ResultShape); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } return App::DocumentObject::StdReturn; }
TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight, const Standard_Real myThickness) { BRepBuilderAPI_MakeWire wireMaker; // Profile : Define Support Points { Handle(TColgp_HArray1OfPnt) gp_array = new TColgp_HArray1OfPnt(1, 4); gp_Pnt p0(-myWidth / 2., 0, 0); gp_Pnt p4(myWidth / 2., 0, 0); // gp_array->SetValue(0, p0); gp_array->SetValue(1, gp_Pnt(-myWidth / 2., -myThickness / 4., 0)); gp_array->SetValue(2, gp_Pnt(0, -myThickness / 2., 0)); gp_array->SetValue(3, gp_Pnt(myWidth / 2., -myThickness / 4., 0)); gp_array->SetValue(4, p4); GeomAPI_Interpolate sp(gp_array, true, 1.0e-3); sp.Perform(); wireMaker.Add(BRepBuilderAPI_MakeEdge(sp.Curve())); } // Body : Prism the Profile TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(wireMaker.Wire()); gp_Vec aPrismVec(0, 0, myHeight); TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec); // Building the Resulting Compound TopoDS_Compound aRes; BRep_Builder aBuilder; aBuilder.MakeCompound(aRes); aBuilder.Add(aRes, myBody); // aBuilder.Add(aRes, myThreading); return aRes; }
App::DocumentObjectExecReturn *Sweep::execute(void) { if (Sections.getSize() == 0) return new App::DocumentObjectExecReturn("No sections linked."); App::DocumentObject* spine = Spine.getValue(); if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) return new App::DocumentObjectExecReturn("No spine linked."); const std::vector<std::string>& subedge = Spine.getSubValues(); TopoDS_Shape path; const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue(); if (!shape._Shape.IsNull()) { try { if (!subedge.empty()) { BRepBuilderAPI_MakeWire mkWire; for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) { TopoDS_Shape subshape = shape.getSubShape(it->c_str()); mkWire.Add(TopoDS::Edge(subshape)); } path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_EDGE) { path = shape._Shape; } else if (shape._Shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape)); path = mkWire.Wire(); } else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape._Shape); for (; it.More(); it.Next()) { if (it.Value().IsNull()) return new App::DocumentObjectExecReturn("In valid element in spine."); if ((it.Value().ShapeType() != TopAbs_EDGE) && (it.Value().ShapeType() != TopAbs_WIRE)) { return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire."); } } Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next()) hEdges->Append(xp.Current()); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires); int len = hWires->Length(); if (len != 1) return new App::DocumentObjectExecReturn("Spine is not connected."); path = hWires->Value(1); } else { return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire."); } } catch (Standard_Failure) { return new App::DocumentObjectExecReturn("Invalid spine."); } } try { TopTools_ListOfShape profiles; const std::vector<App::DocumentObject*>& shapes = Sections.getValues(); std::vector<App::DocumentObject*>::const_iterator it; for (it = shapes.begin(); it != shapes.end(); ++it) { if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId())) return new App::DocumentObjectExecReturn("Linked object is not a shape."); TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getValue(); if (shape.IsNull()) return new App::DocumentObjectExecReturn("Linked shape is invalid."); // Extract first element of a compound if (shape.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator it(shape); for (; it.More(); it.Next()) { if (!it.Value().IsNull()) { shape = it.Value(); break; } } } // There is a weird behaviour of BRepOffsetAPI_MakePipeShell when trying to add the wire as is. // If we re-create the wire then everything works fine. // http://forum.freecadweb.org/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268 if (shape.ShapeType() == TopAbs_FACE) { TopoDS_Wire faceouterWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape)); profiles.Append(faceouterWire); } else if (shape.ShapeType() == TopAbs_WIRE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape)); profiles.Append(mkWire.Wire()); } else if (shape.ShapeType() == TopAbs_VERTEX) { profiles.Append(shape); } else { return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge, wire nor face."); } } Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False; Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False; BRepBuilderAPI_TransitionMode transMode; switch (Transition.getValue()) { case 1: transMode = BRepBuilderAPI_RightCorner; break; case 2: transMode = BRepBuilderAPI_RoundCorner; break; default: transMode = BRepBuilderAPI_Transformed; break; } if (path.ShapeType() == TopAbs_EDGE) { BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path)); path = mkWire.Wire(); } BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path)); mkPipeShell.SetMode(isFrenet); mkPipeShell.SetTransitionMode(transMode); TopTools_ListIteratorOfListOfShape iter; for (iter.Initialize(profiles); iter.More(); iter.Next()) { mkPipeShell.Add(TopoDS_Shape(iter.Value())); } if (!mkPipeShell.IsReady()) Standard_Failure::Raise("shape is not ready to build"); mkPipeShell.Build(); if (isSolid) mkPipeShell.MakeSolid(); this->Shape.setValue(mkPipeShell.Shape()); return App::DocumentObject::StdReturn; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); return new App::DocumentObjectExecReturn(e->GetMessageString()); } catch (...) { return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep"); } }
PyObject* TopoShapeEdgePy::split(PyObject *args) { PyObject* float_or_list; if (!PyArg_ParseTuple(args, "O", &float_or_list)) return 0; try { BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->_Shape)); Standard_Real f = adapt.FirstParameter(); Standard_Real l = adapt.LastParameter(); std::vector<Standard_Real> par; par.push_back(f); if (PyFloat_Check(float_or_list)) { double val = PyFloat_AsDouble(float_or_list); if (val == f || val == l) { PyErr_SetString(PyExc_ValueError, "Cannot split edge at start or end point"); return 0; } else if (val < f || val > l) { PyErr_SetString(PyExc_ValueError, "Value out of parameter range"); return 0; } par.push_back(val); } else if (PyList_Check(float_or_list)) { Py::List list(float_or_list); for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { double val = (double)Py::Float(*it); if (val == f || val == l) { PyErr_SetString(PyExc_ValueError, "Cannot split edge at start or end point"); return 0; } else if (val < f || val > l) { PyErr_SetString(PyExc_ValueError, "Value out of parameter range"); return 0; } par.push_back(val); } } else { PyErr_SetString(PyExc_TypeError, "Either float or list of floats expected"); return 0; } par.push_back(l); std::sort(par.begin(), par.end()); BRepBuilderAPI_MakeWire mkWire; Handle_Geom_Curve c = adapt.Curve().Curve(); std::vector<Standard_Real>::iterator end = par.end() - 1; for (std::vector<Standard_Real>::iterator it = par.begin(); it != end; ++it) { BRepBuilderAPI_MakeEdge mkBuilder(c, it[0], it[1]); mkWire.Add(mkBuilder.Edge()); } return new TopoShapeWirePy(new TopoShape(mkWire.Shape())); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PyExc_Exception, e->GetMessageString()); return 0; } PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); return 0; }
// constructor method int TopoShapeWirePy::PyInit(PyObject* args, PyObject* /*kwd*/) { PyObject *pcObj; if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) { BRepBuilderAPI_MakeWire mkWire; const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape; if (sh.IsNull()) { PyErr_SetString(PyExc_TypeError, "given shape is invalid"); return -1; } if (sh.ShapeType() == TopAbs_EDGE) mkWire.Add(TopoDS::Edge(sh)); else if (sh.ShapeType() == TopAbs_WIRE) mkWire.Add(TopoDS::Wire(sh)); else { PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire"); return -1; } try { getTopoShapePtr()->_Shape = mkWire.Wire(); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PyExc_Exception, e->GetMessageString()); return -1; } } PyErr_Clear(); if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj)) { BRepBuilderAPI_MakeWire mkWire; Py::List list(pcObj); for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { PyObject* item = (*it).ptr(); if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape; if (sh.IsNull()) { PyErr_SetString(PyExc_TypeError, "given shape is invalid"); return -1; } if (sh.ShapeType() == TopAbs_EDGE) mkWire.Add(TopoDS::Edge(sh)); else if (sh.ShapeType() == TopAbs_WIRE) mkWire.Add(TopoDS::Wire(sh)); else { PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire"); return -1; } } else { PyErr_SetString(PyExc_TypeError, "item is not a shape"); return -1; } } try { getTopoShapePtr()->_Shape = mkWire.Wire(); return 0; } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); PyErr_SetString(PyExc_Exception, e->GetMessageString()); return -1; } } PyErr_SetString(PyExc_Exception, "edge or wire or list of edges and wires expected"); return -1; }
int OCCWire::chamfer(std::vector<OCCVertex *> vertices, std::vector<double> distances) { int vertices_size = vertices.size(); int distances_size = distances.size(); BRepFilletAPI_MakeFillet2d MF; try { if (this->getShape().IsNull()) { StdFail_NotDone::Raise("Shapes is Null"); } MF.Init(BRepBuilderAPI_MakeFace(this->getWire())); // creat map of vertices TopTools_IndexedMapOfShape vertMap; for (unsigned i=0; i<vertices.size(); i++) vertMap.Add(vertices[i]->getShape()); bool first = true; TopoDS_Edge firstEdge, nextEdge; TopoDS_Vertex vertex; BRepTools_WireExplorer Ex1; for (Ex1.Init(this->getWire()); Ex1.More(); ) { if(first == true) { firstEdge = Ex1.Current(); first = false; } Ex1.Next(); //if the number of edges is odd don't proceed if(Ex1.More() == Standard_False) break; nextEdge = Ex1.Current(); //get the common vertex of the two edges if (!TopExp::CommonVertex(firstEdge, nextEdge, vertex)) { // disconnected wire first = true; continue; } if (vertMap.Contains(vertex)) { int i = vertMap.FindIndex(vertex) - 1; if (distances_size == 1) { // single distance MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]); } else if (distances_size == vertices_size) { // distance given for each vertex MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]); } else { StdFail_NotDone::Raise("distances argument has wrong size"); } } firstEdge = nextEdge; } // special case for closed wire if (isClosed()) { // find seam vertex TopoDS_Vertex aV1; TopExp::Vertices(this->getWire(), vertex, aV1); // check if seam vertex has chamfer value if (vertMap.Contains(vertex)) { int i = vertMap.FindIndex(vertex) - 1; // map vertices to edges to find edge pair TopTools_IndexedDataMapOfShapeListOfShape mapVertexEdge; TopExp::MapShapesAndAncestors(this->getWire(), TopAbs_VERTEX, TopAbs_EDGE, mapVertexEdge); const TopTools_ListOfShape& edges = mapVertexEdge.FindFromKey(vertex); firstEdge = TopoDS::Edge(edges.First()); nextEdge = TopoDS::Edge(edges.Last()); if (distances_size == 1) { // single distance MF.AddChamfer(firstEdge, nextEdge, distances[0], distances[0]); } else if (distances_size == vertices_size) { // distance given for each vertex MF.AddChamfer(firstEdge, nextEdge, distances[i], distances[i]); } else { StdFail_NotDone::Raise("distances argument has wrong size"); } } } if(MF.Status() != ChFi2d_IsDone) StdFail_NotDone::Raise("chamfer operation failed"); TopTools_IndexedMapOfShape aMap; TopExp::MapShapes(MF.Shape(), TopAbs_WIRE, aMap); if(aMap.Extent() != 1) StdFail_NotDone::Raise("chamfer result did not result in single wire");; //add edges to the wire BRepBuilderAPI_MakeWire wire; BRepTools_WireExplorer Ex2; for(Ex2.Init(TopoDS::Wire(aMap(1))); Ex2.More(); Ex2.Next()) { wire.Add(Ex2.Current()); } this->setShape(wire.Shape()); // possible fix shape if (!this->fixShape()) StdFail_NotDone::Raise("Shapes not valid"); } catch(Standard_Failure &err) { Handle_Standard_Failure e = Standard_Failure::Caught(); const Standard_CString msg = e->GetMessageString(); if (msg != NULL && strlen(msg) > 1) { setErrorMessage(msg); } else { setErrorMessage("Failed to chamfer wire"); } return 0; } return 1; }