bool Geometry::GetVertices(const TopoDS_Shape &brep, Geometry::VertexSet &vertices) { TopExp_Explorer anExp(brep, TopAbs_WIRE); int count=0; for (; anExp.More(); anExp.Next()){ const TopoDS_Wire& w = TopoDS::Wire(anExp.Current()); BRepTools_WireExplorer Ex; for (Ex.Init(w); Ex.More(); Ex.Next()) { //FIXME ifcopenshell already re-order the vertices, so no need to check the orientation, just use the natrual sequence, it works in most of the cases, but some exception still exists, e.g., part of the wall in the turkey building vertices.push_back(new TopoDS_Vertex); vertices.at(vertices.size()-1)=TopoDS::Vertex(Ex.CurrentVertex()); count++; } } // if(count>=1) // cout<<"element: has "<<boost::lexical_cast<string>(count)<<" vertices"<<endl; if(count < 1) cout<<"error! no vertex is found in this building element"<<endl; return count>0; }
int OCCVertex::project(OCCBase *target) { Standard_Real First,Last,Best = 1e200; try { gp_Pnt pnt = BRep_Tool::Pnt(vertex); if (target->shapeType() == TopAbs_EDGE) { Handle(Geom_Curve) Curve = BRep_Tool::Curve(TopoDS::Edge(target->getShape()), First, Last); GeomAPI_ProjectPointOnCurve proj; proj.Init(pnt, Curve, First, Last); gp_Pnt aPnt = proj.NearestPoint(); BRepBuilderAPI_MakeVertex mkVertex(aPnt); this->setShape(mkVertex.Vertex()); } else if (target->shapeType() == TopAbs_WIRE) { BRepTools_WireExplorer exWire; for (exWire.Init(TopoDS::Wire(target->getShape())); exWire.More(); exWire.Next()) { const TopoDS_Edge& edge = exWire.Current(); const Handle(Geom_Curve)& Curve = BRep_Tool::Curve(edge, First, Last); GeomAPI_ProjectPointOnCurve proj; proj.Init(pnt, Curve); gp_Pnt aPnt = proj.NearestPoint(); if (proj.LowerDistance() < Best) { Best = proj.LowerDistance(); pnt = aPnt; } } BRepBuilderAPI_MakeVertex mkVertex(pnt); this->setShape(mkVertex.Vertex()); } else { gp_Pnt org = BRep_Tool::Pnt(vertex); BRepExtrema_DistShapeShape proj(this->getShape(), target->getShape()); proj.Perform(); for (int i = 1; i <= proj.NbSolution(); i++) { gp_Pnt aPnt = proj.PointOnShape2(i); if (org.Distance(aPnt) < Best) { Best = org.Distance(aPnt); pnt = aPnt; } } BRepBuilderAPI_MakeVertex mkVertex(pnt); this->setShape(mkVertex.Vertex()); } } catch(Standard_Failure &err) {
OCCTesselation *OCCWire::tesselate(double angular, double curvature) { OCCTesselation *ret = new OCCTesselation(); try { Standard_Real start, end; OCCStruct3f dtmp; // explore wire edges in connected order int lastSize = 0; BRepTools_WireExplorer exWire; for (exWire.Init(this->getWire()); exWire.More(); exWire.Next()) { const TopoDS_Edge& edge = exWire.Current(); TopLoc_Location loc = edge.Location(); gp_Trsf location = loc.Transformation(); const Handle(Geom_Curve)& curve = BRep_Tool::Curve(edge, start, end); const GeomAdaptor_Curve& aCurve(curve); GCPnts_TangentialDeflection TD(aCurve, start, end, angular, curvature); ret->ranges.push_back(ret->vertices.size()); for (Standard_Integer i = 1; i <= TD.NbPoints(); i++) { gp_Pnt pnt = TD.Value(i).Transformed(location); dtmp.x = (float)pnt.X(); dtmp.y = (float)pnt.Y(); dtmp.z = (float)pnt.Z(); ret->vertices.push_back(dtmp); } ret->ranges.push_back(ret->vertices.size() - lastSize); lastSize = ret->vertices.size(); } } catch(Standard_Failure &err) { return NULL; } return ret; }
Standard_Real ProjectPointOnWire(const TopoDS_Wire& wire, gp_Pnt p) { double smallestDist = DBL_MAX; double alpha = 0.; int edgeIndex = 0; // find edge with closest dist to point p BRepTools_WireExplorer wireExplorer; int iwire = 0; for (wireExplorer.Init(wire); wireExplorer.More(); wireExplorer.Next(), iwire++) { Standard_Real firstParam, lastParam; TopoDS_Edge edge = wireExplorer.Current(); Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, firstParam, lastParam); GeomAPI_ProjectPointOnCurve proj(p, curve, firstParam, lastParam); if (proj.NbPoints() > 0 && proj.LowerDistance() < smallestDist) { smallestDist = proj.LowerDistance(); edgeIndex = iwire; alpha = proj.LowerDistanceParameter(); } } // compute partial length of wire until projection point is reached wireExplorer.Init(wire); double partLength = 0.; for (int iwire = 0; iwire <= edgeIndex; ++iwire) { Standard_Real firstParam; Standard_Real lastParam; TopoDS_Edge edge = wireExplorer.Current(); Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, firstParam, lastParam); GeomAdaptor_Curve adaptorCurve(curve, firstParam, lastParam); if (iwire == edgeIndex) { lastParam = alpha; } partLength += GCPnts_AbscissaPoint::Length(adaptorCurve, firstParam, lastParam); wireExplorer.Next(); } // return relative coordinate double normalizedLength = partLength/GetWireLength(wire); if (normalizedLength > 1.0) { normalizedLength = 1.0; } else if (normalizedLength < 0.0) { normalizedLength = 0.0; } return normalizedLength; }
//---------------------------------------------------------------- // Function: TopoDS_Shape level function to update the core Surface // for any movement or Boolean operation of the body. // Author: Jane Hu //---------------------------------------------------------------- CubitStatus OCCSurface::update_OCC_entity(TopoDS_Face& old_surface, TopoDS_Shape& new_surface, BRepBuilderAPI_MakeShape *op, TopoDS_Vertex* removed_vertex, LocOpe_SplitShape* sp) { //set the Wires TopTools_IndexedMapOfShape M, M2; TopoDS_Shape shape, shape2, shape_edge, shape_vertex; TopExp::MapShapes(old_surface, TopAbs_WIRE, M); TopTools_ListOfShape shapes; BRepFilletAPI_MakeFillet2d* test_op = NULL; for (int ii=1; ii<=M.Extent(); ii++) { TopoDS_Wire wire = TopoDS::Wire(M(ii)); TopTools_ListOfShape shapes; if(op) { test_op = dynamic_cast<BRepFilletAPI_MakeFillet2d*>(op); if(!test_op) shapes.Assign(op->Modified(wire)); if(shapes.Extent() == 0) shapes.Assign(op->Generated(wire)); if(!new_surface.IsNull()) TopExp::MapShapes(new_surface,TopAbs_WIRE, M2); } else if(sp) shapes.Assign(sp->DescendantShapes(wire)); if (shapes.Extent() == 1) { shape = shapes.First(); if(M2.Extent() == 1) { shape2 = TopoDS::Wire(M2(1)); if(!shape.IsSame(shape2)) shape = shape2; } else if(M2.Extent() > 1) shape.Nullify(); } else if(shapes.Extent() > 1) shape.Nullify(); else if(op->IsDeleted(wire) || shapes.Extent() == 0) { TopTools_IndexedMapOfShape M_new; TopExp::MapShapes(new_surface, TopAbs_WIRE, M_new); if (M_new.Extent()== 1) shape = M_new(1); else shape.Nullify(); } else { shape = wire; continue; } //set curves BRepTools_WireExplorer Ex; for(Ex.Init(wire); Ex.More();Ex.Next()) { TopoDS_Edge edge = Ex.Current(); if(op && !test_op) { shapes.Assign(op->Modified(edge)); if(shapes.Extent() == 0) shapes.Assign(op->Generated(edge)); } else if(sp) shapes.Assign(sp->DescendantShapes(edge)); if (shapes.Extent() == 1) { //in fillet creating mothod, one edge could generated a face, so check //it here. TopAbs_ShapeEnum type = shapes.First().TShape()->ShapeType(); if(type != TopAbs_EDGE) shape_edge.Nullify(); else shape_edge = shapes.First(); } else if (shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape_edge = it.Value(); OCCQueryEngine::instance()->copy_attributes(edge, shape_edge); } shape_edge.Nullify(); } else if (op->IsDeleted(edge)) shape_edge.Nullify(); else if (test_op) { if(!test_op->IsModified(edge)) shape_edge = edge; else shape_edge = (test_op->Modified(edge)).First(); } else shape_edge = edge; //update vertex TopoDS_Vertex vertex = Ex.CurrentVertex(); shapes.Clear(); if(test_op) assert(removed_vertex != NULL); if(op && ! test_op ) shapes.Assign(op->Modified(vertex)); else if(sp) shapes.Assign(sp->DescendantShapes(vertex)); if (shapes.Extent() == 1) shape_vertex = shapes.First(); else if(shapes.Extent() > 1) { //update all attributes first. TopTools_ListIteratorOfListOfShape it; it.Initialize(shapes); for(; it.More(); it.Next()) { shape_vertex = it.Value(); OCCQueryEngine::instance()->copy_attributes(vertex, shape_vertex); } shape_vertex.Nullify() ; } else if(op->IsDeleted(vertex) || (test_op && vertex.IsSame( *removed_vertex))) shape_vertex.Nullify() ; else shape_vertex = vertex; if(!vertex.IsSame(shape_vertex) ) OCCQueryEngine::instance()->update_OCC_map(vertex, shape_vertex); if (!edge.IsSame(shape_edge)) OCCQueryEngine::instance()->update_OCC_map(edge, shape_edge); } if (!wire.IsSame(shape)) OCCQueryEngine::instance()->update_OCC_map(wire, shape); } double dTOL = OCCQueryEngine::instance()->get_sme_resabs_tolerance(); if (!old_surface.IsSame(new_surface)) { TopAbs_ShapeEnum shapetype = TopAbs_SHAPE; if(!new_surface.IsNull()) shapetype = new_surface.TShape()->ShapeType(); if(shapetype == TopAbs_FACE || new_surface.IsNull()) OCCQueryEngine::instance()->update_OCC_map(old_surface, new_surface); else { TopTools_IndexedMapOfShape M; TopExp::MapShapes(new_surface, TopAbs_FACE, M); TopoDS_Shape new_shape; if(M.Extent() == 1) new_shape = M(1); else if(M.Extent() > 1) { for(int i = 1; i <= M.Extent(); i++) { GProp_GProps myProps; BRepGProp::SurfaceProperties(old_surface, myProps); double orig_mass = myProps.Mass(); gp_Pnt orig_pnt = myProps.CentreOfMass(); BRepGProp::SurfaceProperties(M(i), myProps); double after_mass = myProps.Mass(); gp_Pnt after_pnt = myProps.CentreOfMass(); if(fabs(-after_mass + orig_mass) <= dTOL && orig_pnt.IsEqual(after_pnt, dTOL)) { new_shape = M(i); break; } } } OCCQueryEngine::instance()->update_OCC_map(old_surface, new_shape); } } return CUBIT_SUCCESS; }
int OCCWire::fillet(std::vector<OCCVertex *> vertices, std::vector<double> radius) { int vertices_size = vertices.size(); int radius_size = radius.size(); BRepFilletAPI_MakeFillet2d MF; try { if (this->getShape().IsNull()) { StdFail_NotDone::Raise("Shapes is Null"); } MF.Init(BRepBuilderAPI_MakeFace(this->getWire())); for (unsigned i=0; i<vertices.size(); i++) { OCCVertex *vertex = vertices[i]; if (radius_size == 1) { // single radius MF.AddFillet(vertex->getVertex(), radius[0]); } else if (radius_size == vertices_size) { // radius given for each vertex MF.AddFillet(vertex->getVertex(), radius[i]); } else { StdFail_NotDone::Raise("radius argument has wrong size"); } } if(MF.Status() != ChFi2d_IsDone) StdFail_NotDone::Raise("fillet not completed"); BRepBuilderAPI_MakeWire wire; TopTools_IndexedMapOfShape aMap; BRepTools_WireExplorer Ex; TopExp::MapShapes(MF.Shape(), TopAbs_WIRE, aMap); if(aMap.Extent() != 1) StdFail_NotDone::Raise("Fillet operation did not result in single wire"); //add edges to the wire Ex.Clear(); for(Ex.Init(TopoDS::Wire(aMap(1))); Ex.More(); Ex.Next()) { wire.Add(Ex.Current()); } this->setShape(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 fillet wire"); } return 0; } return 1; }