/// Create a ChBodyAuxRef with assets for the given TopoDS_Shape std::shared_ptr<ChBodyAuxRef> ChCascadeDoc::CreateBodyFromShape( const TopoDS_Shape& mshape, ///< pass the shape here const double density ///< pass the density here ) { std::shared_ptr<ChBodyAuxRef> mbody(new ChBodyAuxRef); chrono::ChFrame<> frame_ref_to_abs; TopLoc_Location loc_shape_to_abs = mshape.Location(); chrono::cascade::ChCascadeDoc::FromCascadeToChrono(loc_shape_to_abs, frame_ref_to_abs); TopoDS_Shape objshape = mshape; objshape.Location(TopLoc_Location()); // Reset shape location to local ref csys (identity). chrono::ChVector<> mcog; chrono::ChVector<> minertiaXX; chrono::ChVector<> minertiaXY; double mvol; double mmass; chrono::cascade::ChCascadeDoc::GetVolumeProperties(objshape, density, mcog, minertiaXX, minertiaXY, mvol, mmass); mbody->SetFrame_REF_to_abs(frame_ref_to_abs); //mbody->SetFrame_COG_to_REF(frame_ref_to_abs.Invert() * mcog ); chrono::ChFrame<>* frame_cog_to_ref = (chrono::ChFrame<>*)mbody.get(); frame_cog_to_ref->SetPos(mcog); frame_cog_to_ref->SetRot(chrono::QUNIT); return mbody; }
/// Create a ChBodyAuxRef with assets for the given TopoDS_Shape std::shared_ptr<ChBodyAuxRef> ChCascadeDoc::CreateBodyFromShape( const TopoDS_Shape& mshape, ///< pass the shape here const double density, ///< pass the density here const bool collide, const bool visual_asset ) { std::shared_ptr<ChBodyAuxRef> mbody(new ChBodyAuxRef); chrono::ChFrame<> frame_ref_to_abs; TopLoc_Location loc_shape_to_abs = mshape.Location(); chrono::cascade::ChCascadeDoc::FromCascadeToChrono(loc_shape_to_abs, frame_ref_to_abs); TopoDS_Shape objshape = mshape; objshape.Location(TopLoc_Location()); // Reset shape location to local ref csys (identity). chrono::ChVector<> mcog; chrono::ChVector<> minertiaXX; chrono::ChVector<> minertiaXY; double mvol; double mmass; chrono::cascade::ChCascadeDoc::GetVolumeProperties(objshape, density, mcog, minertiaXX, minertiaXY, mvol, mmass); // Set mass and COG and REF references mbody->SetDensity((float)density); mbody->SetMass(mmass); mbody->SetInertiaXX(minertiaXX); mbody->SetInertiaXY(minertiaXY); mbody->SetFrame_REF_to_abs(frame_ref_to_abs); chrono::ChFrame<> frame_cog_to_ref; frame_cog_to_ref.SetPos(mcog); frame_cog_to_ref.SetRot(chrono::QUNIT); mbody->SetFrame_COG_to_REF(frame_cog_to_ref); // Add a visualization asset if needed if (visual_asset) { auto trimesh = std::make_shared<geometry::ChTriangleMeshConnected>(); ChCascadeMeshTools::fillTriangleMeshFromCascade(*trimesh, objshape); auto trimesh_shape = std::make_shared<ChTriangleMeshShape>(); trimesh_shape->SetMesh(trimesh); mbody->AddAsset(trimesh_shape); // Add a collision shape if needed if (collide) { mbody->GetCollisionModel()->ClearModel(); mbody->GetCollisionModel()->AddTriangleMesh(trimesh, false, false); mbody->GetCollisionModel()->BuildModel(); mbody->SetCollide(true); } } return mbody; }
TopoDS_Shape Subassembly::lookupShape ( QVector<uint>& id_path ) const { TopoDS_Shape shape; if ( subassembly_->id() == id_path[0] ) { id_path.erase( id_path.begin() ); shape = subassembly_->lookupShape( id_path ); shape.Location( location_ * shape.Location() ); } return shape; }
//======================================================================= //function : GetPosition //purpose : //======================================================================= gp_Ax3 GEOMUtils::GetPosition (const TopoDS_Shape& theShape) { gp_Ax3 aResult; if (theShape.IsNull()) return aResult; // Axes aResult.Transform(theShape.Location().Transformation()); if (theShape.ShapeType() == TopAbs_FACE) { Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape)); if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) { Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS); gp_Pln aPln = aGPlane->Pln(); aResult = aPln.Position(); // In case of reverse orinetation of the face invert the plane normal // (the face's normal does not mathc the plane's normal in this case) if(theShape.Orientation() == TopAbs_REVERSED) { gp_Dir Vx = aResult.XDirection(); gp_Dir N = aResult.Direction().Mirrored(Vx); gp_Pnt P = aResult.Location(); aResult = gp_Ax3(P, N, Vx); } } } // Origin gp_Pnt aPnt; TopAbs_ShapeEnum aShType = theShape.ShapeType(); if (aShType == TopAbs_VERTEX) { aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); } else { if (aShType == TopAbs_COMPOUND) { aShType = GetTypeOfSimplePart(theShape); } GProp_GProps aSystem; if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) BRepGProp::LinearProperties(theShape, aSystem); else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) BRepGProp::SurfaceProperties(theShape, aSystem); else BRepGProp::VolumeProperties(theShape, aSystem); aPnt = aSystem.CentreOfMass(); } aResult.SetLocation(aPnt); return aResult; }
TopoDS_Shape Subassembly::lookupShape ( QStringList& path_components ) const { // The front path component is the name of a figure with ".type" appended // to it. int dot_pos = path_components.front().lastIndexOf( '.' ); QString name = path_components.front().left( dot_pos ); QString type = path_components.front().right( path_components.front().length() - dot_pos - 1 ); TopoDS_Shape shape; if ( subassembly_->name() == name && subassembly_->type() == type ) { path_components.erase( path_components.begin() ); // The shape returned here must be modified by the transformation // of the subassembly. shape = subassembly_->lookupShape( path_components ); shape.Location( location_ * shape.Location() ); } return shape; }
virtual bool ForShape(TopoDS_Shape& mshape, TopLoc_Location& mloc, char* mname, int mlevel, TDF_Label& mlabel) { for (int i=0; i<mlevel; i++) GetLog()<< " "; GetLog() << "-Name :" << mname; if (mlevel==0) GetLog() << " (root)"; GetLog() << "\n"; for (int i=0; i<mlevel; i++) GetLog()<< " "; gp_XYZ mtr = mloc.Transformation().TranslationPart(); GetLog() << " pos at: "<< mtr.X() <<" "<< mtr.Y() << " "<<mtr.Z() <<" (absolute) \n"; for (int i=0; i<mlevel; i++) GetLog()<< " "; gp_XYZ mtr2 = mshape.Location().Transformation().TranslationPart(); GetLog() << " pos at: "<< mtr2.X() <<" "<< mtr2.Y() << " "<<mtr2.Z() <<" (.Location)\n"; return true; }
virtual bool ForShape(TopoDS_Shape& mshape, TopLoc_Location& mloc, char* mname, int mlevel, TDF_Label& mlabel) { if (this->level_names.size() > mlevel) { if ( wildcard_compare(level_names[mlevel].c_str(), mname )) { if (level_copy[mlevel] != -2) { level_copy[mlevel] = level_copy[mlevel]-1; if (level_copy[mlevel] < -1) level_copy[mlevel] = -1; } if ((level_copy[mlevel] == 0) || (level_copy[mlevel] == -2)) { if (mlevel == this->level_names.size()-1) { // Found!!! if (this->set_location_to_root) mshape.Location(mloc); // For single istance: only 1st found shape is considered if (!res_found) { res_found = true; res_shape = mshape; res_loc = mloc; res_level = mlevel; res_label = mlabel; } // Add to the shape compound, for multiple results aBuilder.Add(res_comp, mshape); } return true; // proceed! } return false; // break, matching name but not #ID, not needed to go deeper in levels } return false; // break, not matching, not needed to go deeper in levels } else return false; // break, not needed to go deeper in levels than in string wildcard }
//================================================================ // Function : TexturesExt_Presentation::sampleKitchen // Purpose : kitchen with texturized items in it. //================================================================ void TexturesExt_Presentation::sampleKitchen() { TopoDS_Shape aShape; if (!loadShape(aShape, "Kitchen\\Room.brep")) return; gp_Trsf aTrsf; gp_Ax3 NewCoordSystem (gp_Pnt(-1,-1, -1),gp_Dir(0,0,1)); gp_Ax3 CurrentCoordSystem(gp_Pnt(0,0,0),gp_Dir(0,0,1)); aTrsf.SetDisplacement(CurrentCoordSystem, NewCoordSystem); aShape.Location(TopLoc_Location(aTrsf)); moveScale(aShape); // draw kitchen room whithout one wall (to better see the insides) TopTools_IndexedMapOfShape aFaces; TopExp::MapShapes(aShape, TopAbs_FACE, aFaces); Standard_Integer nbFaces = aFaces.Extent(); // create a wooden kitchen floor // the floor's face will be textured with texture from chataignier.gif DISP(Texturize(aFaces(5),"plancher.gif",1,1,2,1)); // texturize other faces of the room with texture from wallpaper.gif (walls) DISP(Texturize(aFaces(1),"wallpaper.gif",1,1,8,6)); DISP(Texturize(aFaces(3),"wallpaper.gif",1,1,8,6)); DISP(Texturize(aFaces(4),"wallpaper.gif",1,1,8,6)); // DISP(drawShape(aFaces(1), Quantity_NOC_LIGHTPINK, Standard_False)); // DISP(drawShape(aFaces(3), Quantity_NOC_LIGHTPINK, Standard_False)); // DISP(drawShape(aFaces(4), Quantity_NOC_LIGHTPINK, Standard_False)); // texturize furniture items with "wooden" texture if (loadShape(aShape, "Kitchen\\MODERN_Table_1.brep")) { moveScale(aShape); DISP(Texturize(aShape, "chataignier.gif")); } if (loadShape(aShape, "Kitchen\\MODERN_Chair_1.brep")) { moveScale(aShape); DISP(Texturize(aShape, "chataignier.gif")); } if (loadShape(aShape, "Kitchen\\MODERN_Cooker_1.brep")) { moveScale(aShape); aFaces.Clear(); TopExp::MapShapes(aShape, TopAbs_FACE, aFaces); nbFaces = aFaces.Extent(); for (Standard_Integer i = 1; i <= nbFaces; i++) { if (i >= 59) DISP(drawShape(aFaces(i), Graphic3d_NOM_STEEL, Standard_False)); else if (i >= 29) DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False)); else if (i == 28) DISP(Texturize(aFaces(i), "cookerplate.gif")); else DISP(Texturize(aFaces(i), "chataignier.gif")); } } if (loadShape(aShape, "Kitchen\\MODERN_Cooker_1_opened.brep")) { moveScale(aShape); DISP(Texturize(aShape, "chataignier.gif")); } if (loadShape(aShape, "Kitchen\\MODERN_Exhaust_1.brep")) { moveScale(aShape); DISP(drawShape(aShape, Graphic3d_NOM_STONE, Standard_False)); } if (loadShape(aShape, "Kitchen\\MODERN_MVCooker_1.brep")) { moveScale(aShape); DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False)); } if (loadShape(aShape, "Kitchen\\MODERN_MVCooker_1_opened.brep")) { moveScale(aShape); DISP(drawShape(aShape, Graphic3d_NOM_SILVER, Standard_False)); } if (loadShape(aShape, "Kitchen\\MODERN_Sink_1.brep")) { moveScale(aShape); aFaces.Clear(); TopExp::MapShapes(aShape, TopAbs_FACE, aFaces); nbFaces = aFaces.Extent(); for (Standard_Integer i = 1; i <= nbFaces; i++) { if (i < 145) DISP(drawShape(aFaces(i), Graphic3d_NOM_ALUMINIUM, Standard_False)); else if (i == 145) DISP(Texturize(aFaces(i), "cookerplate.gif")); else DISP(Texturize(aFaces(i), "chataignier.gif")); } } if (loadShape(aShape, "Kitchen\\MODERN_Sink_1_opened.brep")) { moveScale(aShape); DISP(Texturize(aShape, "chataignier.gif")); } if (loadShape(aShape, "Kitchen\\MODERN_Refrigerator_1.brep")) { moveScale(aShape); DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False)); } if (loadShape(aShape, "Kitchen\\MODERN_Refrigerator_1_opened.brep")) { moveScale(aShape); DISP(drawShape(aShape, Graphic3d_NOM_CHROME, Standard_False)); } getViewer()->Update(); }
bool ProfileBased::checkLineCrossesFace(const gp_Lin &line, const TopoDS_Face &face) { #if 1 BRepBuilderAPI_MakeEdge mkEdge(line); TopoDS_Wire wire = ShapeAnalysis::OuterWire(face); BRepExtrema_DistShapeShape distss(wire, mkEdge.Shape(), Precision::Confusion()); if (distss.IsDone()) { if (distss.Value() > Precision::Confusion()) return false; // build up map vertex->edge TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge; TopExp::MapShapesAndAncestors(wire, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge); for (Standard_Integer i=1; i<= distss.NbSolution(); i++) { if (distss.PointOnShape1(i).Distance(distss.PointOnShape2(i)) > Precision::Confusion()) continue; BRepExtrema_SupportType type = distss.SupportTypeShape1(i); if (type == BRepExtrema_IsOnEdge) { TopoDS_Edge edge = TopoDS::Edge(distss.SupportOnShape1(i)); BRepAdaptor_Curve adapt(edge); // create a plane (pnt,dir) that goes through the intersection point and is built of // the vectors of the sketch normal and the rotation axis const gp_Dir& normal = BRepAdaptor_Surface(face).Plane().Axis().Direction(); gp_Dir dir = line.Direction().Crossed(normal); gp_Pnt pnt = distss.PointOnShape1(i); Standard_Real t; distss.ParOnEdgeS1(i, t); gp_Pnt p_eps1 = adapt.Value(std::max<double>(adapt.FirstParameter(), t-10*Precision::Confusion())); gp_Pnt p_eps2 = adapt.Value(std::min<double>(adapt.LastParameter(), t+10*Precision::Confusion())); // now check if we get a change in the sign of the distances Standard_Real dist_p_eps1_pnt = gp_Vec(p_eps1, pnt).Dot(gp_Vec(dir)); Standard_Real dist_p_eps2_pnt = gp_Vec(p_eps2, pnt).Dot(gp_Vec(dir)); // distance to the plane must be noticeable if (fabs(dist_p_eps1_pnt) > 5*Precision::Confusion() && fabs(dist_p_eps2_pnt) > 5*Precision::Confusion()) { if (dist_p_eps1_pnt * dist_p_eps2_pnt < 0) return true; } } else if (type == BRepExtrema_IsVertex) { // for a vertex check the two adjacent edges if there is a change of sign TopoDS_Vertex vertex = TopoDS::Vertex(distss.SupportOnShape1(i)); const TopTools_ListOfShape& edges = vertex2Edge.FindFromKey(vertex); if (edges.Extent() == 2) { // create a plane (pnt,dir) that goes through the intersection point and is built of // the vectors of the sketch normal and the rotation axis BRepAdaptor_Surface adapt(face); const gp_Dir& normal = adapt.Plane().Axis().Direction(); gp_Dir dir = line.Direction().Crossed(normal); gp_Pnt pnt = distss.PointOnShape1(i); // from the first edge get a point next to the intersection point const TopoDS_Edge& edge1 = TopoDS::Edge(edges.First()); BRepAdaptor_Curve adapt1(edge1); Standard_Real dist1 = adapt1.Value(adapt1.FirstParameter()).SquareDistance(pnt); Standard_Real dist2 = adapt1.Value(adapt1.LastParameter()).SquareDistance(pnt); gp_Pnt p_eps1; if (dist1 < dist2) p_eps1 = adapt1.Value(adapt1.FirstParameter() + 2*Precision::Confusion()); else p_eps1 = adapt1.Value(adapt1.LastParameter() - 2*Precision::Confusion()); // from the second edge get a point next to the intersection point const TopoDS_Edge& edge2 = TopoDS::Edge(edges.Last()); BRepAdaptor_Curve adapt2(edge2); Standard_Real dist3 = adapt2.Value(adapt2.FirstParameter()).SquareDistance(pnt); Standard_Real dist4 = adapt2.Value(adapt2.LastParameter()).SquareDistance(pnt); gp_Pnt p_eps2; if (dist3 < dist4) p_eps2 = adapt2.Value(adapt2.FirstParameter() + 2*Precision::Confusion()); else p_eps2 = adapt2.Value(adapt2.LastParameter() - 2*Precision::Confusion()); // now check if we get a change in the sign of the distances Standard_Real dist_p_eps1_pnt = gp_Vec(p_eps1, pnt).Dot(gp_Vec(dir)); Standard_Real dist_p_eps2_pnt = gp_Vec(p_eps2, pnt).Dot(gp_Vec(dir)); // distance to the plane must be noticeable if (fabs(dist_p_eps1_pnt) > Precision::Confusion() && fabs(dist_p_eps2_pnt) > Precision::Confusion()) { if (dist_p_eps1_pnt * dist_p_eps2_pnt < 0) return true; } } } } } return false; #else // This is not as easy as it looks, because a distance of zero might be OK if // the axis touches the sketchshape in in a linear edge or a vertex // Note: This algorithm does not catch cases where the sketchshape touches the // axis in two or more points // Note: And it only works on closed outer wires TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(face); BRepBuilderAPI_MakeEdge mkEdge(line); if (!mkEdge.IsDone()) throw Base::RuntimeError("Revolve: Unexpected OCE failure"); BRepAdaptor_Curve axis(TopoDS::Edge(mkEdge.Shape())); TopExp_Explorer ex; int intersections = 0; std::vector<gp_Pnt> intersectionpoints; // Note: We need to look at every edge separately to catch coincident lines for (ex.Init(outerWire, TopAbs_EDGE); ex.More(); ex.Next()) { BRepAdaptor_Curve edge(TopoDS::Edge(ex.Current())); Extrema_ExtCC intersector(axis, edge); if (intersector.IsDone()) { for (int i = 1; i <= intersector.NbExt(); i++) { #if OCC_VERSION_HEX >= 0x060500 if (intersector.SquareDistance(i) < Precision::Confusion()) { #else if (intersector.Value(i) < Precision::Confusion()) { #endif if (intersector.IsParallel()) { // A line that is coincident with the axis produces three intersections // 1 with the line itself and 2 with the adjacent edges intersections -= 2; } else { Extrema_POnCurv p1, p2; intersector.Points(i, p1, p2); intersectionpoints.push_back(p1.Value()); intersections++; } } } } } // Note: We might check this inside the loop but then we have to rely on TopExp_Explorer // returning the wire's edges in adjacent order (because of the coincident line checking) if (intersections > 1) { // Check that we don't touch the sketchface just in two identical vertices if ((intersectionpoints.size() == 2) && (intersectionpoints[0].IsEqual(intersectionpoints[1], Precision::Confusion()))) return false; else return true; } return false; #endif } void ProfileBased::remapSupportShape(const TopoDS_Shape& newShape) { TopTools_IndexedMapOfShape faceMap; TopExp::MapShapes(newShape, TopAbs_FACE, faceMap); // here we must reset the placement otherwise the geometric matching doesn't work Part::TopoShape shape = this->Shape.getValue(); TopoDS_Shape sh = shape.getShape(); sh.Location(TopLoc_Location()); shape.setShape(sh); std::vector<App::DocumentObject*> refs = this->getInList(); for (std::vector<App::DocumentObject*>::iterator it = refs.begin(); it != refs.end(); ++it) { std::vector<App::Property*> props; (*it)->getPropertyList(props); for (std::vector<App::Property*>::iterator jt = props.begin(); jt != props.end(); ++jt) { if (!(*jt)->isDerivedFrom(App::PropertyLinkSub::getClassTypeId())) continue; App::PropertyLinkSub* link = static_cast<App::PropertyLinkSub*>(*jt); if (link->getValue() != this) continue; std::vector<std::string> subValues = link->getSubValues(); std::vector<std::string> newSubValues; for (std::vector<std::string>::iterator it = subValues.begin(); it != subValues.end(); ++it) { std::string shapetype; if (it->size() > 4 && it->substr(0,4) == "Face") { shapetype = "Face"; } else if (it->size() > 4 && it->substr(0,4) == "Edge") { shapetype = "Edge"; } else if (it->size() > 6 && it->substr(0,6) == "Vertex") { shapetype = "Vertex"; } else { newSubValues.push_back(*it); continue; } bool success = false; TopoDS_Shape element; try { element = shape.getSubShape(it->c_str()); } catch (Standard_Failure&) { // This shape doesn't even exist, so no chance to do some tests newSubValues.push_back(*it); continue; } try { // as very first test check if old face and new face are parallel planes TopoDS_Shape newElement = Part::TopoShape(newShape).getSubShape(it->c_str()); if (isParallelPlane(element, newElement)) { newSubValues.push_back(*it); success = true; } } catch (Standard_Failure&) { } // try an exact matching if (!success) { for (int i=1; i<faceMap.Extent(); i++) { if (isQuasiEqual(element, faceMap.FindKey(i))) { std::stringstream str; str << shapetype << i; newSubValues.push_back(str.str()); success = true; break; } } } // if an exact matching fails then try to compare only the geometries if (!success) { for (int i=1; i<faceMap.Extent(); i++) { if (isEqualGeometry(element, faceMap.FindKey(i))) { std::stringstream str; str << shapetype << i; newSubValues.push_back(str.str()); success = true; break; } } } // the new shape couldn't be found so keep the old sub-name if (!success) newSubValues.push_back(*it); } link->setValue(this, newSubValues); } } }
//======================================================================= //function : MakeScaledPrism //purpose : //======================================================================= TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase, const gp_Vec& theVector, const Standard_Real theScaleFactor, const gp_Pnt& theCDG, bool isCDG) { TopoDS_Shape aShape; BRep_Builder B; // 1. aCDG = geompy.MakeCDG(theBase) gp_Pnt aCDG = theCDG; if (!isCDG) { gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase); aCDG = aPos.Location(); } TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape(); // Process case of several given shapes if (theShapeBase.ShapeType() == TopAbs_COMPOUND || theShapeBase.ShapeType() == TopAbs_SHELL) { int nbSub = 0; TopoDS_Shape aShapeI; TopoDS_Compound aCompound; B.MakeCompound(aCompound); TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True); for (; It.More(); It.Next()) { nbSub++; aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true); B.Add(aCompound, aShapeI); } if (nbSub == 1) aShape = aShapeI; else if (nbSub > 1) aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True); return aShape; } // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor) // Bug 6839: Check for standalone (not included in faces) degenerated edges TopTools_IndexedDataMapOfShapeListOfShape aEFMap; TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap); Standard_Integer i, nbE = aEFMap.Extent(); for (i = 1; i <= nbE; i++) { TopoDS_Shape anEdgeSh = aEFMap.FindKey(i); if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) { const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i); if (aFaces.IsEmpty()) Standard_ConstructionError::Raise ("Scaling aborted : cannot scale standalone degenerated edge"); } } // Perform Scaling gp_Trsf aTrsf; aTrsf.SetScale(aCDG, theScaleFactor); BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False); TopoDS_Shape aScale = aBRepTrsf.Shape(); // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH) gp_Trsf aTrsf3; aTrsf3.SetTranslation(theVector); TopLoc_Location aLocOrig = aScale.Location(); gp_Trsf aTrsfOrig = aLocOrig.Transformation(); TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig); TopoDS_Shape aBase2 = aScale.Located(aLocRes); // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH) gp_Pnt aCDG_2 = aCDG.Translated(theVector); TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape(); // 5. Vector = geompy.MakeVector(aCDG, aCDG_2) TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape(); TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec); TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge); // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False) Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape; aBases->Append(theShapeBase); aBases->Append(aBase2); Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape; aLocs->Append(aShapeCDG_1); aLocs->Append(aShapeCDG_2); aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false); // 7. Make a solid, if possible if (theShapeBase.ShapeType() == TopAbs_FACE) { BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); TopExp_Explorer expF (aShape, TopAbs_FACE); Standard_Integer ifa = 0; for (; expF.More(); expF.Next()) { aSewing.Add(expF.Current()); ifa++; } if (ifa > 0) { aSewing.Perform(); TopoDS_Shape aShell; TopoDS_Shape sh = aSewing.SewedShape(); if (sh.ShapeType() == TopAbs_FACE && ifa == 1) { // case for creation of shell from one face TopoDS_Shell ss; B.MakeShell(ss); B.Add(ss,sh); aShell = ss; } else { TopExp_Explorer exp (sh, TopAbs_SHELL); Standard_Integer ish = 0; for (; exp.More(); exp.Next()) { aShell = exp.Current(); ish++; } if (ish != 1) aShell = sh; } BRepCheck_Shell chkShell (TopoDS::Shell(aShell)); if (chkShell.Closed() == BRepCheck_NoError) { TopoDS_Solid Sol; B.MakeSolid(Sol); B.Add(Sol, aShell); BRepClass3d_SolidClassifier SC (Sol); SC.PerformInfinitePoint(Precision::Confusion()); if (SC.State() == TopAbs_IN) { B.MakeSolid(Sol); B.Add(Sol, aShell.Reversed()); } aShape = Sol; } } } return aShape; }
App::DocumentObjectExecReturn *RuledSurface::execute(void) { try { App::DocumentObjectExecReturn* ret; // get the first input shape TopoDS_Shape S1; ret = getShape(Curve1, S1); if (ret) return ret; // get the second input shape TopoDS_Shape S2; ret = getShape(Curve2, S2); if (ret) return ret; // check for expected type if (S1.IsNull() || S2.IsNull()) return new App::DocumentObjectExecReturn("Linked shapes are empty."); if (S1.ShapeType() != TopAbs_EDGE && S1.ShapeType() != TopAbs_WIRE) return new App::DocumentObjectExecReturn("Linked shape is neither edge nor wire."); if (S2.ShapeType() != TopAbs_EDGE && S2.ShapeType() != TopAbs_WIRE) return new App::DocumentObjectExecReturn("Linked shape is neither edge nor wire."); // https://forum.freecadweb.org/viewtopic.php?f=8&t=24052 // // if both shapes are sub-elements of one common shape then the fill algorithm // leads to problems if the shape has set a placement // The workaround is to reset the placement before calling BRepFill and then // applying the placement to the output shape TopLoc_Location Loc; if (Curve1.getValue() == Curve2.getValue()) { Loc = S1.Location(); if (!Loc.IsIdentity() && Loc == S2.Location()) { S1.Location(TopLoc_Location()); S2.Location(TopLoc_Location()); } } // make both shapes to have the same type Standard_Boolean isWire = Standard_False; if (S1.ShapeType() == TopAbs_WIRE) isWire = Standard_True; if (isWire) { if (S2.ShapeType() == TopAbs_EDGE) S2 = BRepLib_MakeWire(TopoDS::Edge(S2)); } else { // S1 is an edge, if S2 is a wire convert S1 to a wire, too if (S2.ShapeType() == TopAbs_WIRE) { S1 = BRepLib_MakeWire(TopoDS::Edge(S1)); isWire = Standard_True; } } if (Orientation.getValue() == 0) { // Automatic Handle(Adaptor3d_HCurve) a1; Handle(Adaptor3d_HCurve) a2; if (!isWire) { BRepAdaptor_Curve adapt1(TopoDS::Edge(S1)); BRepAdaptor_Curve adapt2(TopoDS::Edge(S2)); a1 = new BRepAdaptor_HCurve(adapt1); a2 = new BRepAdaptor_HCurve(adapt2); } else { BRepAdaptor_CompCurve adapt1(TopoDS::Wire(S1)); BRepAdaptor_CompCurve adapt2(TopoDS::Wire(S2)); a1 = new BRepAdaptor_HCompCurve(adapt1); a2 = new BRepAdaptor_HCompCurve(adapt2); } if (!a1.IsNull() && !a2.IsNull()) { // get end points of 1st curve Standard_Real first, last; first = a1->FirstParameter(); last = a1->LastParameter(); if (S1.Closed()) last = (first + last)/2; gp_Pnt p1 = a1->Value(first); gp_Pnt p2 = a1->Value(last); if (S1.Orientation() == TopAbs_REVERSED) { std::swap(p1, p2); } // get end points of 2nd curve first = a2->FirstParameter(); last = a2->LastParameter(); if (S2.Closed()) last = (first + last)/2; gp_Pnt p3 = a2->Value(first); gp_Pnt p4 = a2->Value(last); if (S2.Orientation() == TopAbs_REVERSED) { std::swap(p3, p4); } // Form two triangles (P1,P2,P3) and (P4,P3,P2) and check their normals. // If the dot product is negative then it's assumed that the resulting face // is twisted, hence the 2nd edge is reversed. gp_Vec v1(p1, p2); gp_Vec v2(p1, p3); gp_Vec n1 = v1.Crossed(v2); gp_Vec v3(p4, p3); gp_Vec v4(p4, p2); gp_Vec n2 = v3.Crossed(v4); if (n1.Dot(n2) < 0) { S2.Reverse(); } } } else if (Orientation.getValue() == 2) { // Reverse S2.Reverse(); } TopoDS_Shape ruledShape; if (!isWire) { ruledShape = BRepFill::Face(TopoDS::Edge(S1), TopoDS::Edge(S2)); } else { ruledShape = BRepFill::Shell(TopoDS::Wire(S1), TopoDS::Wire(S2)); } // re-apply the placement in case we reset it if (!Loc.IsIdentity()) ruledShape.Move(Loc); Loc = ruledShape.Location(); if (!Loc.IsIdentity()) { // reset the placement of the shape because the Placement // property will be changed ruledShape.Location(TopLoc_Location()); Base::Matrix4D transform; TopoShape::convertToMatrix(Loc.Transformation(), transform); this->Placement.setValue(Base::Placement(transform)); } this->Shape.setValue(ruledShape); return App::DocumentObject::StdReturn; } catch (Standard_Failure& e) { return new App::DocumentObjectExecReturn(e.GetMessageString()); } catch (...) { return new App::DocumentObjectExecReturn("General error in RuledSurface::execute()"); } }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IPosition aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; if (aType == POSITION_SHAPE || aType == POSITION_SHAPE_COPY) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aRefStartLCS = aCI.GetStartLCS(); Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aShapeStartLCS = aRefStartLCS->GetValue(); TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue(); if (aShapeBase.IsNull() || aShapeStartLCS.IsNull() || aShapeEndLCS.IsNull() || aShapeEndLCS.ShapeType() != TopAbs_FACE) return 0; gp_Trsf aTrsf; gp_Ax3 aStartAx3, aDestAx3; // End LCS aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS); // Start LCS aStartAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeStartLCS); // Set transformation aTrsf.SetDisplacement(aStartAx3, aDestAx3); // Perform transformation BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); aShape = aBRepTrsf.Shape(); } else if (aType == POSITION_SHAPE_FROM_GLOBAL || aType == POSITION_SHAPE_FROM_GLOBAL_COPY) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue(); if (aShapeBase.IsNull() || aShapeEndLCS.IsNull() || aShapeEndLCS.ShapeType() != TopAbs_FACE) return 0; gp_Trsf aTrsf; gp_Ax3 aStartAx3, aDestAx3; // End LCS aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS); // Set transformation aTrsf.SetDisplacement(aStartAx3, aDestAx3); // Perform transformation BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False); aShape = aBRepTrsf.Shape(); } else if (aType == POSITION_ALONG_PATH) { Handle(GEOM_Function) aRefShape = aCI.GetShape(); Handle(GEOM_Function) aPathShape = aCI.GetPath(); Standard_Real aParameter = aCI.GetDistance(); bool aReversed = aCI.GetReverse(); if (aReversed) aParameter = 1 - aParameter; TopoDS_Shape aShapeBase = aRefShape->GetValue(); TopoDS_Shape aPath = aPathShape->GetValue(); TopoDS_Wire aWire; if (aShapeBase.IsNull() || aPath.IsNull()) return 0; if ( aPath.ShapeType() == TopAbs_EDGE ) { TopoDS_Edge anEdge = TopoDS::Edge(aPath); aWire = BRepBuilderAPI_MakeWire(anEdge); } else if ( aPath.ShapeType() == TopAbs_WIRE) aWire = TopoDS::Wire(aPath); else return 0; Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet(); Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw ); Handle(BRepFill_LocationLaw) aLocation = new BRepFill_Edge3DLaw(aWire, aLocationLaw); aLocation->TransformInCompatibleLaw( 0.01 ); //Calculate a Parameter Standard_Real aFirstParam1 = 0, aLastParam1 = 0; // Parameters of the First edge Standard_Real aFirstParam2 = 0, aLastParam2 = 0; // Parameters of the Last edge aLocation->CurvilinearBounds(aLocation->NbLaw(), aFirstParam2, aLastParam2); if ( aLocation->NbLaw() > 1) aLocation->CurvilinearBounds(1, aFirstParam1, aLastParam1); else if ( aLocation->NbLaw() == 1 ) aFirstParam1 = aFirstParam2; else return 0; Standard_Real aParam = (aFirstParam1 + (aLastParam2 - aFirstParam1)*aParameter ); TopoDS_Shape CopyShape = aShapeBase; BRepFill_SectionPlacement Place( aLocation, aShapeBase ); TopLoc_Location Loc2(Place.Transformation()), Loc1; Loc1 = CopyShape.Location(); CopyShape.Location(Loc2.Multiplied(Loc1)); aLocation->D0( aParam, CopyShape ); aShape = CopyShape; } else return 0; if (aShape.IsNull()) return 0; aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }