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