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; }
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; }
//---------------------------------------------------------------- // 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; }