-// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeFix_Face.hxx>
#include <ShapeFix_Shell.hxx>
-#include <ShapeFix_Shape.hxx>
-#include <ShapeFix_ShapeTolerance.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
-#include <BRepCheck_Analyzer.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepGProp.hxx>
#include <GeomFill_Trihedron.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
+#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
#include <GProp_GProps.hxx>
#include "utilities.h"
+#define GROUP_DOWN 0
+#define GROUP_UP 1
+#define GROUP_SIDE1 2
+#define GROUP_SIDE2 3
+#define GROUP_OTHER 4
+
+static const Standard_Real TolPipeSurf = 5.e-4;
+
+static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
+ const TopTools_IndexedMapOfShape &theIndices,
+ Handle(TColStd_HArray1OfInteger) *theGroupIds);
+
+static void StoreGroups(GEOMImpl_IPipe *theCI,
+ Handle(TColStd_HArray1OfInteger) *theGroups);
+
+// after OCCT improvement
+static bool DoGroups1(const TopoDS_Shape &theProfile,
+ BRepOffsetAPI_MakePipeShell &theSweep,
+ TopTools_SequenceOfShape *theGroups);
+
+static bool CreateGroups1(const TopoDS_Shape &theProfile,
+ BRepOffsetAPI_MakePipeShell &theSweep,
+ GEOMImpl_IPipe *theCI);
//=======================================================================
//function : GetID
//=======================================================================
//function : EvaluateBestSweepMode
-//purpose : auxilary for right call of MakePipe and MakePipeShell
+//purpose : auxiliary for right call of MakePipe and MakePipeShell
//=======================================================================
static GeomFill_Trihedron EvaluateBestSweepMode(const TopoDS_Shape& Spine)
{
return theMode;
}
+//=======================================================================
+//function : BuildPipeShell
+//purpose : Builds a pipe shell. If failed, try to build in Descrete Trihedron
+// mode. Returns Standard_True if the building is done successfully.
+//=======================================================================
+static Standard_Boolean BuildPipeShell(BRepOffsetAPI_MakePipeShell &theBuilder)
+{
+ theBuilder.SetForceApproxC1(Standard_True);
+
+ theBuilder.Build();
+
+ Standard_Boolean isDone = theBuilder.IsDone();
+
+ if (!isDone ||
+ theBuilder.ErrorOnSurface() > TolPipeSurf) {
+ // Try to use Descrete Trihedron mode.
+ theBuilder.SetDiscreteMode();
+ theBuilder.Build();
+ isDone = theBuilder.IsDone();
+ }
+
+ return isDone;
+}
//=======================================================================
//function : FillForOtherEdges
-//purpose : auxilary for CreatePipeForShellSections()
+//purpose : auxiliary for CreatePipeForShellSections()
//=======================================================================
static bool FillForOtherEdges(const TopoDS_Shape& F1,
const TopoDS_Shape& E1,
//=======================================================================
//function : FillCorrespondingEdges
-//purpose : auxilary for CreatePipeForShellSections()
+//purpose : auxiliary for CreatePipeForShellSections()
//=======================================================================
static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
const TopoDS_Shape& FS2,
if (!aBuilder.IsReady()) {
return false;
}
- aBuilder.Build();
+
+ BuildPipeShell(aBuilder);
+
TopoDS_Shape aShape = aBuilder.Shape();
- /*
- TopoDS_Compound C;
- BRep_Builder B;
- B.MakeCompound(C);
- B.Add(C,aShape);
- B.Add(C,FS1);
- B.Add(C,FS2);
- BRepTools::Write(C,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
- */
ShapeAnalysis_Edge sae;
double tol = Max(BRep_Tool::Tolerance(TopoDS::Face(FS1)),
BRep_Tool::Tolerance(TopoDS::Face(FS2)));
//=======================================================================
//function : FillCorrespondingEdges
-//purpose : auxilary for CreatePipeShellsWithoutPath()
+//purpose : auxiliary for CreatePipeShellsWithoutPath()
//=======================================================================
static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
const TopoDS_Shape& FS2,
//=======================================================================
//function : FindNextPairOfFaces
-//purpose : auxilary for CreatePipeForShellSections()
+//purpose : auxiliary for CreatePipeForShellSections()
//=======================================================================
static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces1,
bool stat = FillForOtherEdges(F1other,E1,V1,FF);
if (!stat) {
if (aCI) delete aCI;
- Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not mapping other egdes");
+ Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not map other edges");
}
FindNextPairOfFaces(F1other, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
//=======================================================================
//function : FindFirstPairFaces
-//purpose : auxilary for Execute()
+//purpose : auxiliary for Execute()
//=======================================================================
static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
TopoDS_Vertex& V1, TopoDS_Vertex& V2,
FS2 = Fs(numface);
}
+//=======================================================================
+//function : RemoveFaces
+//purpose : This function returns theShapeFrom without faces of the shape
+// theFacesToRm. It returns a shell if theShapeFrom is a solid or
+// a compound otherwise. Auxiliary for CreatePipeWithDifferentSections
+// method.
+//=======================================================================
+static TopoDS_Shape RemoveFaces(const TopoDS_Shape &theShapeFrom,
+ const TopoDS_Shape &theFacesToRm)
+{
+ TopTools_IndexedMapOfShape aMapFaces;
+ TopExp_Explorer anExp(theShapeFrom, TopAbs_FACE);
+ BRep_Builder aBuilder;
+ TopoDS_Shape aResult;
+
+ if (theShapeFrom.ShapeType() == TopAbs_SOLID) {
+ // Create shell
+ aBuilder.MakeShell(TopoDS::Shell(aResult));
+ } else {
+ // Create compound
+ aBuilder.MakeCompound(TopoDS::Compound(aResult));
+ }
+
+ TopExp::MapShapes(theFacesToRm, TopAbs_FACE, aMapFaces);
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &aFace = anExp.Current();
+
+ if (!aMapFaces.Contains(aFace)) {
+ aBuilder.Add(aResult, aFace);
+ }
+ }
+
+ return aResult;
+}
+
//=======================================================================
//function : CreatePipeWithDifferentSections
//purpose :
//=======================================================================
TopoDS_Shape GEOMImpl_PipeDriver::CreatePipeWithDifferentSections
- (const TopoDS_Wire& theWirePath,
- const Handle(TopTools_HSequenceOfShape) theHSeqBases,
- const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
- const Standard_Boolean theWithContact,
- const Standard_Boolean theWithCorrect)
+ (const TopoDS_Wire &theWirePath,
+ const Handle(TopTools_HSequenceOfShape) theHSeqBases,
+ const Handle(TopTools_HSequenceOfShape) theHSeqLocs,
+ const Standard_Boolean theWithContact,
+ const Standard_Boolean theWithCorrect,
+ const Standard_Boolean IsBySteps,
+ Handle(TColStd_HArray1OfInteger) *theGroups)
{
TopoDS_Shape aShape;
TopTools_SequenceOfShape aSeqBases;
TopTools_SequenceOfShape aSeqLocs;
TopTools_SequenceOfShape aSeqFaces;
+ Standard_Boolean NeedCreateSolid = Standard_False;
Standard_Integer i = 1;
for (i = 1; i <= nbBases; i++) {
//if for section was specified face with a few wires then a few
// pipes were build and make solid
- Standard_Boolean NeedCreateSolid = Standard_False;
if (aTypeBase == TopAbs_SHELL) {
// create wire as boundary contour if shell is no closed
// get free boundary shapes
}
}
if (nbEdges<Edges.Length()) {
- // one of edges was splitted => we have to update WirePath
+ // one of edges was split => we have to update WirePath
BRep_Builder B;
TopoDS_Wire W;
B.MakeWire(W);
}
}
- // check curvature of wire for condition that
- // max summary angle between directions along
- // wire path must be < 4*PI. If not - split wire
- // and seguences of shapes, perform pipe for each
- // and make sewing after that
- double fp,lp;
- gp_Pnt P1,P2;
- gp_Vec Vec1,Vec2;
- double SumAng = 0;
- if ( Edges.Length() > 0 ) {
- Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
- C->D1(fp,P1,Vec1);
- C->D1(lp,P2,Vec2);
- SumAng = fabs(Vec1.Angle(Vec2));
- Vec1 = Vec2;
- P1 = P2;
- }
TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
- int LastLoc = 1;
- //cout<<"Edges.Length()="<<Edges.Length()<<endl;
- for (i=2; i<=Edges.Length(); i++) {
- TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
- double tol = BRep_Tool::Tolerance(edge);
- Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
- C->D1(lp,P2,Vec2);
- double ang = fabs(Vec1.Angle(Vec2));
- SumAng += ang;
- if (SumAng>4*M_PI) {
- SumAng = ang;
- SplitEdgeNums.Append(i-1);
- int j;
- for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
- TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
- gp_Pnt P = BRep_Tool::Pnt(aVert);
- if (P1.Distance(P) < tol) {
- SplitLocNums.Append(j);
- LastLoc = j;
- break;
- }
+
+ if (IsBySteps) {
+ // Fill SplitEdgeNums and SplitLocNums with intermediate location indices
+ // and corresponding edge indices.
+ Standard_Integer i = 1;
+ Standard_Integer j;
+ TopoDS_Vertex aVert;
+ gp_Pnt aP;
+
+ for (j = 2; j < aSeqLocs.Length(); j++) {
+ SplitLocNums.Append(j);
+ aVert = TopoDS::Vertex(aSeqLocs.Value(j));
+ aP = BRep_Tool::Pnt(aVert);
+
+ while (i < Edges.Length()) {
+ Standard_Real aFp;
+ Standard_Real aLp;
+ TopoDS_Edge anEdge = TopoDS::Edge(Edges.Value(i));
+ Standard_Real aTol = BRep_Tool::Tolerance(anEdge);
+ Handle(Geom_Curve) aC = BRep_Tool::Curve(anEdge, aFp, aLp);
+ gp_Pnt aPLast;
+
+ aC->D0(aLp, aPLast);
+ i++;
+
+ if (aP.Distance(aPLast) < aTol) {
+ SplitEdgeNums.Append(i - 1);
+ break;
}
}
+ }
+ } else {
+ // check curvature of wire for condition that
+ // max summary angle between directions along
+ // wire path must be < 4*PI. If not - split wire
+ // and seguences of shapes, perform pipe for each
+ // and make sewing after that
+ double fp,lp;
+ gp_Pnt P1,P2;
+ gp_Vec Vec1,Vec2;
+ double SumAng = 0;
+ if ( Edges.Length() > 0 ) {
+ Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
+ C->D1(fp,P1,Vec1);
+ C->D1(lp,P2,Vec2);
+ SumAng = fabs(Vec1.Angle(Vec2));
Vec1 = Vec2;
P1 = P2;
+ }
+ int LastLoc = 1;
+ //cout<<"Edges.Length()="<<Edges.Length()<<endl;
+ for (i=2; i<=Edges.Length(); i++) {
+ TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
+ double tol = BRep_Tool::Tolerance(edge);
+ Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
+ C->D1(lp,P2,Vec2);
+ double ang = fabs(Vec1.Angle(Vec2));
+ SumAng += ang;
+ if (SumAng>4*M_PI) {
+ SumAng = ang;
+ SplitEdgeNums.Append(i-1);
+ int j;
+ for (j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
+ TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
+ gp_Pnt P = BRep_Tool::Pnt(aVert);
+ if (P1.Distance(P) < tol) {
+ SplitLocNums.Append(j);
+ LastLoc = j;
+ break;
+ }
+ }
+ }
+ Vec1 = Vec2;
+ P1 = P2;
+ }
}
+ bool isCreateGroups = (theGroups != NULL);
+
if (SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0) {
- TopTools_SequenceOfShape aSeqRes;
+ TopTools_SequenceOfShape aSeqRes;
+ TopTools_DataMapOfShapeSequenceOfShape aMapResGroups[5];
+ Standard_Integer iGrp;
int nn, num1 = 1, num2 = 1;
for (nn=1; nn<=SplitEdgeNums.Length(); nn++) {
// create wirepath and sequences of shapes
if (!aBuilder.IsReady()) {
Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
}
- aBuilder.Build();
+
+ Standard_Boolean isDone = BuildPipeShell(aBuilder);
+
+ if (isDone && NeedCreateSolid && nn == 1) {
+ // Make solid for the first step.
+ isDone = aBuilder.MakeSolid();
+ }
+
+ if (!isDone) {
+ Standard_ConstructionError::Raise("Pipe construction failure");
+ }
+
TopoDS_Shape resShape = aBuilder.Shape();
+
+ if (NeedCreateSolid && nn == 1) {
+ // Remove top lid from the result.
+ resShape = RemoveFaces(resShape, aBuilder.LastShape());
+ }
+
aSeqRes.Append(resShape);
+
+ // Create groups.
+ if (isCreateGroups) {
+ // Make groups.
+ TopTools_SequenceOfShape aGroups[5];
+
+ TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
+ if (!DoGroups1(aProfile, aBuilder, aGroups)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ // Get shapes from all groups.
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
+ }
+ }
}
// create wirepath and sequences of shapes for last part
BRep_Builder B;
if (!aBuilder.IsReady()) {
Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
}
- aBuilder.Build();
+
+ Standard_Boolean isDone = BuildPipeShell(aBuilder);
+
+ if (isDone && NeedCreateSolid) {
+ isDone = aBuilder.MakeSolid();
+ }
+
+ if (!isDone) {
+ Standard_ConstructionError::Raise("Pipe construction failure");
+ }
+
TopoDS_Shape resShape = aBuilder.Shape();
+
+ if (NeedCreateSolid) {
+ // Remove bottom lid from the result.
+ resShape = RemoveFaces(resShape, aBuilder.FirstShape());
+ }
+
aSeqRes.Append(resShape);
+
+ // Create groups.
+ if (isCreateGroups) {
+ // Make groups.
+ TopTools_SequenceOfShape aGroups[5];
+
+ TopoDS_Shape aProfile = aTmpSeqBases.Value(1);
+ if (!DoGroups1(aProfile, aBuilder, aGroups)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ // Get shapes from all groups.
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ aMapResGroups[iGrp].Bind(resShape, aGroups[iGrp]);
+ }
+ }
+
// make sewing for result
Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
aSewing->SetTolerance(Precision::Confusion());
}
aSewing->Perform();
aShape = aSewing->SewedShape();
+
+ if (NeedCreateSolid && aShape.ShapeType() == TopAbs_SHELL) {
+ // Build a solid.
+ BRepBuilderAPI_MakeSolid aMkSolid;
+
+ aMkSolid.Add(TopoDS::Shell(aShape));
+
+ if (!aMkSolid.IsDone()) {
+ Standard_ConstructionError::Raise("Can't create solid pipe");
+ }
+
+ TopoDS_Solid aSolid = aMkSolid.Solid();
+ BRepClass3d_SolidClassifier aSC(aSolid);
+
+ aSC.PerformInfinitePoint(Precision::Confusion());
+
+ if (aSC.State() == TopAbs_IN) {
+ aShape = aSolid.Reversed();
+ } else {
+ aShape = aSolid;
+ }
+ }
+
+ if (isCreateGroups) {
+ // Replase Group shapes by modified ones.
+ TopTools_SequenceOfShape aSeqGroups[5];
+
+ // For each group.
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ // For each pipe
+ for (i = 1; i <= aSeqRes.Length(); ++i) {
+ if (iGrp == GROUP_DOWN && i > 1) {
+ // For DOWN group we use only the first pipe.
+ continue;
+ }
+
+ if (iGrp == GROUP_UP && i < aSeqRes.Length()) {
+ // For UP group we use only the last pipe.
+ continue;
+ }
+
+ const TopTools_SequenceOfShape &aShapes =
+ aMapResGroups[iGrp].Find(aSeqRes.Value(i));
+ Standard_Integer j;
+
+ // For each sub-shape of pipe
+ for (j = 1; j <= aShapes.Length(); ++j) {
+ const TopoDS_Shape &aGrpShape = aShapes.Value(j);
+
+ if (aSewing->IsModifiedSubShape(aGrpShape)) {
+ // Use the shape modified by sewing.
+ const TopoDS_Shape &aModifGrpShape =
+ aSewing->ModifiedSubShape(aGrpShape);
+
+ aSeqGroups[iGrp].Append(aModifGrpShape);
+ } else {
+ // Use the shape as it is.
+ aSeqGroups[iGrp].Append(aGrpShape);
+ }
+ }
+ }
+ }
+
+ // Fill groups
+ TopTools_IndexedMapOfShape anIndices;
+
+ TopExp::MapShapes(aShape, anIndices);
+
+ if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+ }
}
else {
// old implementation without splitting
aBuilder.SetTolerance(aTolConf, aTolConf, aTolAng);
- aBuilder.Build();
+ Standard_Boolean isDone = BuildPipeShell(aBuilder);
+
+ if (isDone && NeedCreateSolid) {
+ isDone = aBuilder.MakeSolid();
+ }
+
+ if (!isDone) {
+ Standard_ConstructionError::Raise("Pipe construction failure");
+ }
aShape = aBuilder.Shape();
+
+ if (isCreateGroups) {
+ // Make groups.
+ TopTools_SequenceOfShape aSeqGroups[5];
+
+ TopoDS_Shape aProfile = usedBases.Value(1);
+ if (!DoGroups1(aProfile, aBuilder, aSeqGroups)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ // Fill the groups.
+ //Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+ TopTools_IndexedMapOfShape anIndices;
+ const TopoDS_Shape aResult = aBuilder.Shape();
+
+ TopExp::MapShapes(aResult, anIndices);
+
+ if (!FillGroups(aSeqGroups, anIndices, theGroups)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+ }
aSeqFaces.Append(aShape);
for (j = 1; j <=usedBases.Length(); j++)
aBuilder.Delete(usedBases.Value(j));
}
-
- //for case if section is face
- if (aSeqFaces.Length() >1) {
- BRep_Builder aB;
- TopoDS_Compound aComp;
- aB.MakeCompound(aComp);
- for (i = 1; i <= aSeqFaces.Length(); i++)
- aB.Add(aComp,aSeqFaces.Value(i));
- aShape = aComp;
- }
}
return aShape;
//=======================================================================
//function : CreatePipeForShellSections
-//purpose : auxilary for Execute()
+//purpose : auxiliary for Execute()
//=======================================================================
static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
GEOMImpl_IPipe* aCI)
{
- //cout<<"CreatePipeForShellSections"<<endl;
- //TopoDS_Shape res;
int i,j;
BRep_Builder B;
Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations();
Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
+ Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
Standard_Integer nbBases = aBasesObjs->Length(),
nbSubBases = (aSubBasesObjs.IsNull() ? 0 :aSubBasesObjs->Length()),
Standard_ConstructionError::Raise("Number of sections is not equal to number of subsections ");
}
- //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
-
TopTools_SequenceOfShape VLocs;
for (i=1; i<=nbBases; i++) {
Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
for (; i<=Edges.Length(); i++)
B.Add(W,Edges.Value(i));
Wires.Append(W);
- //cout<<"Wires.Length()="<<Wires.Length()<<endl;
}
if (Wires.Length() != nbLocs-1) {
("One of location shapes is not lied on the path");
}
- //TopTools_SequenceOfShape aSeqBases;
- //TopTools_SequenceOfShape aSeqSubBases;
- //TopTools_SequenceOfShape aSeqFaces;
- TopoDS_Compound aComp;
+ TopTools_SequenceOfShape aGroups[5];
+ TopoDS_Compound aComp;
B.MakeCompound(aComp);
for (i = 1; i < nbBases; i++) {
TopoDS_Wire WPath = TopoDS::Wire(Wires.Value(i));
continue;
TopAbs_ShapeEnum aType2 = aShBase2.ShapeType();
- //BRepTools::Write(aShBase1,"/dn02/users_Linux/skl/work/Bugs/14857/base1.brep");
-
bool OkSec = (aType1==TopAbs_SHELL || aType1==TopAbs_FACE) &&
(aType2==TopAbs_SHELL || aType2==TopAbs_FACE);
if (!OkSec) {
CreateFewSolids = true;
}
- /*
- // check orientation of sections
- bool NeedReverse = false;
- {
- // first section
- anExp.Init(aShBase1, TopAbs_FACE);
- TopoDS_Shape aFace = anExp.Current();
- TColgp_SequenceOfPnt aPnts;
- double xc=0, yc=0, zc=0;
- for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
- TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
- aPnts.Append(BRep_Tool::Pnt(V));
- xc += aPnts.Last().X();
- yc += aPnts.Last().Y();
- zc += aPnts.Last().Z();
- }
- gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
- gp_Vec V1(PC,aPnts.Value(1));
- gp_Vec V2(PC,aPnts.Value(2));
- gp_Vec VN = V1.Crossed(V2);
- for (int ip=2; ip<aPnts.Length(); ip++) {
- V1 = gp_Vec(PC,aPnts.Value(ip));
- V2 = gp_Vec(PC,aPnts.Value(ip+1));
- VN.Add(V1.Crossed(V2));
- }
- gp_Vec PathNorm;
- gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i)));
- TopExp_Explorer WE;
- for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
- TopoDS_Edge edge = TopoDS::Edge(WE.Current());
- double tol = BRep_Tool::Tolerance(edge);
- TopoDS_Vertex VF = sae.FirstVertex(edge);
- gp_Pnt PF = BRep_Tool::Pnt(VF);
- if (PF.Distance(PLoc) < tol) {
- double fp,lp;
- Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
- gp_Pnt P1,P2;
- C->D0(fp,P1);
- if (P1.Distance(PLoc) < tol) {
- C->D0(fp+(lp-fp)/100,P2);
- }
- else {
- C->D0(lp,P1);
- C->D0(lp+(fp-lp)/100,P2);
- }
- PathNorm = gp_Vec(P1,P2);
- break;
- }
- else {
- TopoDS_Vertex VL = sae.LastVertex(edge);
- gp_Pnt PL = BRep_Tool::Pnt(VL);
- if (PL.Distance(PLoc) < tol) {
- double fp,lp;
- Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
- gp_Pnt P1,P2;
- C->D0(fp,P1);
- if (P1.Distance(PLoc) < tol) {
- C->D0(fp+(lp-fp)/100,P2);
- }
- else {
- C->D0(lp,P1);
- C->D0(lp+(fp-lp)/100,P2);
- }
- PathNorm = gp_Vec(P2,P1);
- break;
- }
- }
- }
- cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
- cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
- if (fabs(VN.Angle(PathNorm))>PI/2.) {
- NeedReverse = true;
- aShBase1.Reverse();
- }
- }
- {
- // second section
- anExp.Init(aShBase2, TopAbs_FACE);
- TopoDS_Shape aFace = anExp.Current();
- TColgp_SequenceOfPnt aPnts;
- double xc=0, yc=0, zc=0;
- for (anExp.Init(aFace, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
- TopoDS_Vertex V = TopoDS::Vertex(anExp.Current());
- aPnts.Append(BRep_Tool::Pnt(V));
- xc += aPnts.Last().X();
- yc += aPnts.Last().Y();
- zc += aPnts.Last().Z();
- }
- gp_Pnt PC(xc/aPnts.Length(), yc/aPnts.Length(), zc/aPnts.Length());
- gp_Vec V1(PC,aPnts.Value(1));
- gp_Vec V2(PC,aPnts.Value(2));
- gp_Vec VN = V1.Crossed(V2);
- for (int ip=2; ip<aPnts.Length(); ip++) {
- V1 = gp_Vec(PC,aPnts.Value(ip));
- V2 = gp_Vec(PC,aPnts.Value(ip+1));
- VN.Add(V1.Crossed(V2));
- }
- gp_Vec PathNorm;
- gp_Pnt PLoc = BRep_Tool::Pnt(TopoDS::Vertex(VLocs(i+1)));
- TopExp_Explorer WE;
- for (WE.Init(WPath, TopAbs_EDGE); WE.More(); WE.Next()) {
- TopoDS_Edge edge = TopoDS::Edge(WE.Current());
- double tol = BRep_Tool::Tolerance(edge);
- TopoDS_Vertex VF = sae.FirstVertex(edge);
- gp_Pnt PF = BRep_Tool::Pnt(VF);
- if (PF.Distance(PLoc) < tol) {
- double fp,lp;
- Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
- gp_Pnt P1,P2;
- C->D0(fp,P1);
- if (P1.Distance(PLoc) < tol) {
- C->D0(fp+(lp-fp)/100,P2);
- }
- else {
- C->D0(lp,P1);
- C->D0(lp+(fp-lp)/100,P2);
- }
- PathNorm = gp_Vec(P2,P1);
- break;
- }
- else {
- TopoDS_Vertex VL = sae.LastVertex(edge);
- gp_Pnt PL = BRep_Tool::Pnt(VL);
- if (PL.Distance(PLoc) < tol) {
- double fp,lp;
- Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
- gp_Pnt P1,P2;
- C->D0(fp,P1);
- if (P1.Distance(PLoc) < tol) {
- C->D0(fp+(lp-fp)/100,P2);
- }
- else {
- C->D0(lp,P1);
- C->D0(lp+(fp-lp)/100,P2);
- }
- PathNorm = gp_Vec(P2,P1);
- break;
- }
- }
- }
- //cout<<"VN("<<VN.X()<<","<<VN.Y()<<","<<VN.Z()<<")"<<endl;
- //cout<<"PathNorm("<<PathNorm.X()<<","<<PathNorm.Y()<<","<<PathNorm.Z()<<")"<<endl;
- if (fabs(VN.Angle(PathNorm))>PI/2.)
- aShBase2.Reverse();
- }
- */
-
if (!CreateFewSolids) {
// we can create only one solid
TopoDS_Shape aWire1, aWire2;
if (aCI) delete aCI;
Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
}
- aBuilder.Build();
- TopoDS_Shape aShape = aBuilder.Shape();
+
+ BuildPipeShell(aBuilder);
+
+ TopoDS_Shape aShape = aBuilder.Shape();
+ TopTools_SequenceOfShape aLocalGroups[5];
+
+ // Create groups.
+ if (isGenerateGroups) {
+ // Make groups.
+ if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ // Clear the groups Down and Up.
+ aLocalGroups[GROUP_DOWN].Clear();
+ aLocalGroups[GROUP_UP].Clear();
+ }
+
TopoDS_Shell aShell;
B.MakeShell(aShell);
for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
}
for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
B.Add(aShell,anExp.Current());
+
+ if (isGenerateGroups && i == 1) {
+ aLocalGroups[GROUP_DOWN].Append(anExp.Current());
+ }
}
for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
B.Add(aShell,anExp.Current());
+
+ if (isGenerateGroups && i == nbBases - 1) {
+ aLocalGroups[GROUP_UP].Append(anExp.Current());
+ }
}
// make sewing for this shell
Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
else {
B.Add(aComp,aShell);
}
+
+ if (isGenerateGroups) {
+ Standard_Integer iGrp;
+
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ Standard_Integer j;
+
+ // For each sub-shape of pipe
+ for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+ const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+ if (aSewing->IsModifiedSubShape(aGrpShape)) {
+ // Use the shape modified by sewing.
+ const TopoDS_Shape &aModifGrpShape =
+ aSewing->ModifiedSubShape(aGrpShape);
+
+ aGroups[iGrp].Append(aModifGrpShape);
+ } else {
+ // Use the shape as it is.
+ aGroups[iGrp].Append(aGrpShape);
+ }
+ }
+ }
+ }
}
}
else {
bool stat = FillForOtherEdges(FS1,E1,V11,FF);
if (!stat) {
if (aCI) delete aCI;
- Standard_ConstructionError::Raise("FindForOtherEdges: Can not mapping other egdes");
+ Standard_ConstructionError::Raise("FindForOtherEdges: Can not map other edges");
}
}
if (aCI) delete aCI;
Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
}
- aBuilder.Build();
- TopoDS_Shape aShape = aBuilder.Shape();
+
+ BuildPipeShell(aBuilder);
+
+ TopoDS_Shape aShape = aBuilder.Shape();
+ TopTools_SequenceOfShape aLocalGroups[5];
+
+ // Create groups.
+ if (isGenerateGroups) {
+ // Make groups.
+ if (!DoGroups1(aWire1, aBuilder, aLocalGroups)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ // Clear the groups Down and Up.
+ aLocalGroups[GROUP_DOWN].Clear();
+ aLocalGroups[GROUP_UP].Clear();
+
+ if (i == 1) {
+ aLocalGroups[GROUP_DOWN].Append(F1);
+ }
+
+ if (i == nbBases - 1) {
+ aLocalGroups[GROUP_UP].Append(F2);
+ }
+ }
+
TopoDS_Shell aShell;
B.MakeShell(aShell);
for (anExp.Init(aShape, TopAbs_FACE); anExp.More(); anExp.Next()) {
else {
B.Add(aComp,aShell);
}
+
+ if (isGenerateGroups) {
+ // Replase Group shapes by modified ones.
+ Standard_Integer iGrp;
+
+ // For each group.
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ Standard_Integer j;
+
+ // For each sub-shape of pipe
+ for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+ const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+ if (aSewing->IsModifiedSubShape(aGrpShape)) {
+ // Use the shape modified by sewing.
+ const TopoDS_Shape &aModifGrpShape =
+ aSewing->ModifiedSubShape(aGrpShape);
+
+ aGroups[iGrp].Append(aModifGrpShape);
+ } else {
+ // Use the shape as it is.
+ aGroups[iGrp].Append(aGrpShape);
+ }
+ }
+ }
+ }
}
}
+ }
+ }
+
+ if (isGenerateGroups) {
+ // Fill the groups.
+ Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aComp, anIndices);
+
+ if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
}
+
+ StoreGroups(aCI, aGroupIds);
}
- //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
return aComp;
}
//=======================================================================
//function : CreatePipeShellsWithoutPath
-//purpose : auxilary for Execute()
+//purpose : auxiliary for Execute()
//=======================================================================
static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
{
Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
// vertex for recognition
Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
+ Standard_Boolean isGenerateGroups = aCIDS->GetGenerateGroups();
Standard_Integer nbBases = aBasesObjs->Length(),
nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
}
+ TopTools_SequenceOfShape aGroups[5];
TopTools_SequenceOfShape SecVs,Bases;
for (i=1; i<=nbBases; i++) {
// vertex
}
TopTools_MapOfShape aFaces1,aFaces2;
+ TopTools_MapOfShape aBndEdges1;
+
for (anExp.Init(aShBase1, TopAbs_FACE); anExp.More(); anExp.Next()) {
- aFaces1.Add(anExp.Current());
+ const TopoDS_Shape &aBaseFace1 = anExp.Current();
+
+ if (aFaces1.Add(aBaseFace1)) {
+ // Get boundary edges.
+ TopExp_Explorer anExpE(aBaseFace1, TopAbs_EDGE);
+
+ for (; anExpE.More(); anExpE.Next()) {
+ const TopoDS_Shape &aBaseEdge1 = anExpE.Current();
+
+ if (!aBndEdges1.Add(aBaseEdge1)) {
+ aBndEdges1.Remove(aBaseEdge1);
+ }
+ }
+ }
}
for (anExp.Init(aShBase2, TopAbs_FACE); anExp.More(); anExp.Next()) {
aFaces2.Add(anExp.Current());
if (aCI) delete aCI;
Standard_ConstructionError::Raise("Can not create correct pipe");
}
- MESSAGE (" correspondences for sub-shapes of first pair of faces is found");
+ MESSAGE (" correspondences for sub-shapes of first pair of faces found");
FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
- MESSAGE (" other correspondences is found, make pipe for all pairs of faces");
+ MESSAGE (" other correspondences found, make pipe for all pairs of faces");
// make pipe for each pair of faces
- // auxilary map vertex->edge for created pipe edges
+ // auxiliary map vertex->edge for created pipe edges
TopTools_IndexedDataMapOfShapeShape VPE;
ShapeAnalysis_Edge sae;
//cout<<"FF.Extent()="<<FF.Extent()<<endl;
TopExp_Explorer anExpE(F1,TopAbs_EDGE);
TopTools_SequenceOfShape aNewFs;
+ TopTools_SequenceOfShape aLocalGroups[5];
+
//int nbee=0;
for (; anExpE.More(); anExpE.Next()) {
TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
if (VPE.Contains(E1)) {
aNewFs.Append(VPE.FindFromKey(E1));
#ifdef _DEBUG_
- MESSAGE (" using existed face");
+ MESSAGE (" using existing face");
#endif
continue;
}
B.Add(W,E2);
B.Add(W,E3);
B.Add(W,E4.Reversed());
- //cout<<" wire for edge "<<nbee<<" is created"<<endl;
- //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
// make surface
GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
if (CE4->Degree()<3)
CE4->IncreaseDegree(3);
- //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
- // <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
- //if (fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
- // os<<"DrawTrSurf_BSplineCurve"<<endl;
- // GeomTools::Write(CE1,os);
- // fic.close();
- //}
Handle(Geom_Surface) BS;
try {
GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
anInt.Load(aDir1,aDir2);
anInt.Perform();
- Handle(Geom_Curve) iso = anInt.Curve();
+ const Handle(Geom_BSplineCurve) iso = anInt.Curve();
fp = iso->FirstParameter();
lp = iso->LastParameter();
step = (lp-fp)/(NbP-1);
TopoDS_Face FixedFace = sff->Face();
aNewFs.Append(FixedFace);
VPE.Add(E1,FixedFace);
- //cout<<" face for edge "<<nbee<<" is created"<<endl;
- //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
+
+ if (isGenerateGroups) {
+ if (aBndEdges1.Contains(E1)) {
+ // This is a boundary face.
+ aLocalGroups[GROUP_OTHER].Append(FixedFace);
+ }
+ }
}
// make shell
TopoDS_Shell aShell;
B.Add(aShell,F1);
B.Add(aShell,F2);
+ // Create groups.
+ if (isGenerateGroups && i == 1) {
+ aLocalGroups[GROUP_DOWN].Append(F1);
+ }
+
+ if (isGenerateGroups && i == nbBases - 1) {
+ aLocalGroups[GROUP_UP].Append(F2);
+ }
+
// make sewing for this shell
Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
aSewing->SetTolerance(Precision::Confusion());
aSewing->Perform();
MESSAGE (" shell for face "<<nbff<<" is created");
const TopoDS_Shape aSewShape = aSewing->SewedShape();
- //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
if (aSewShape.ShapeType() == TopAbs_SHELL) {
aShell = TopoDS::Shell(aSewShape);
GProp_GProps aSystem;
B.Add(aComp,aShell);
MESSAGE (" solid for face "<<nbff<<" is not created");
}
- //cout<<" solid for face "<<nbff<<" is created"<<endl;
- //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
- //sfs->Perform();
- //TopoDS_Shell FixedShell = sfs->Shell();
- /*
- GProp_GProps aSystem;
- BRepGProp::VolumeProperties(FixedShell, aSystem);
- if (aSystem.Mass()<0) {
- //cout<<"aSewShape is reversed"<<endl;
- FixedShell.Reverse();
- }
- if (BRep_Tool::IsClosed(FixedShell)) {
- TopoDS_Solid aSolid;
- B.MakeSolid(aSolid);
- B.Add(aSolid,aShell);
- B.Add(aComp,aSolid);
- }
- else {
- B.Add(aComp,FixedShell);
+ if (isGenerateGroups) {
+ Standard_Integer iGrp;
+
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ Standard_Integer j;
+
+ // For each sub-shape of pipe
+ for (j = 1; j <= aLocalGroups[iGrp].Length(); ++j) {
+ const TopoDS_Shape &aGrpShape = aLocalGroups[iGrp].Value(j);
+
+ if (aSewing->IsModifiedSubShape(aGrpShape)) {
+ // Use the shape modified by sewing.
+ const TopoDS_Shape &aModifGrpShape =
+ aSewing->ModifiedSubShape(aGrpShape);
+
+ aGroups[iGrp].Append(aModifGrpShape);
+ } else {
+ // Use the shape as it is.
+ aGroups[iGrp].Append(aGrpShape);
+ }
+ }
+ }
}
- */
}
}
- //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
+ if (isGenerateGroups) {
+ // Fill the groups.
+ Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+ TopTools_IndexedMapOfShape anIndices;
+
+ TopExp::MapShapes(aComp, anIndices);
+
+ if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ StoreGroups(aCI, aGroupIds);
+ }
+
return aComp;
}
//=======================================================================
//function : CreatePipeBiNormalAlongVector
-//purpose : auxilary for Execute()
+//purpose : auxiliary for Execute()
//=======================================================================
static TopoDS_Shape CreatePipeBiNormalAlongVector(const TopoDS_Wire& aWirePath,
GEOMImpl_IPipe* aCI)
gp_Vec aVec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
gp_Dir BiNormal(aVec);
PipeBuilder.SetMode(BiNormal);
- PipeBuilder.Build();
- if (aShapeBase.ShapeType() == TopAbs_FACE) {
+
+ Standard_Boolean isDone = BuildPipeShell(PipeBuilder);
+
+ if (isDone && aShapeBase.ShapeType() == TopAbs_FACE) {
PipeBuilder.MakeSolid();
}
+ if (!CreateGroups1(aProf, PipeBuilder, aCIBN)) {
+ if (aCIBN) delete aCIBN;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
return PipeBuilder.Shape();
}
+//=======================================================================
+//function : FillGroups
+//purpose : auxiliary for DoGroups()
+//=======================================================================
+bool FillGroups(const TopTools_SequenceOfShape *theGroups,
+ const TopTools_IndexedMapOfShape &theIndices,
+ Handle(TColStd_HArray1OfInteger) *theGroupIds)
+{
+ Standard_Integer i;
+
+ for (i = 0; i < 5; ++i) {
+ if (!theGroups[i].IsEmpty()) {
+ const Standard_Integer aNbShapes = theGroups[i].Length();
+ Standard_Integer j;
+
+ theGroupIds[i] = new TColStd_HArray1OfInteger(1, aNbShapes);
+
+ for (j = 1; j <= aNbShapes; ++j) {
+ const TopoDS_Shape &aShape = theGroups[i].Value(j);
+ const Standard_Integer anIndex = theIndices.FindIndex(aShape);
+
+ if (anIndex == 0) {
+ return false;
+ }
+
+ theGroupIds[i]->SetValue(j, anIndex);
+ }
+ }
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : StoreGroups
+//purpose : auxiliary for CreateGroups()
+//=======================================================================
+void StoreGroups(GEOMImpl_IPipe *theCI,
+ Handle(TColStd_HArray1OfInteger) *theGroups)
+{
+ if (theGroups[GROUP_DOWN].IsNull() == Standard_False) {
+ theCI->SetGroupDown(theGroups[GROUP_DOWN]);
+ }
+
+ if (theGroups[GROUP_UP].IsNull() == Standard_False) {
+ theCI->SetGroupUp(theGroups[GROUP_UP]);
+ }
+
+ if (theGroups[GROUP_SIDE1].IsNull() == Standard_False) {
+ theCI->SetGroupSide1(theGroups[GROUP_SIDE1]);
+ }
+
+ if (theGroups[GROUP_SIDE2].IsNull() == Standard_False) {
+ theCI->SetGroupSide2(theGroups[GROUP_SIDE2]);
+ }
+
+ if (theGroups[GROUP_OTHER].IsNull() == Standard_False) {
+ theCI->SetGroupOther(theGroups[GROUP_OTHER]);
+ }
+}
+
+//=======================================================================
+//function : CreateDownUpGroups
+//purpose : auxiliary for DoGroups()
+//=======================================================================
+static bool CreateDownUpGroups(BRepPrimAPI_MakeSweep *theSweep,
+ TopTools_SequenceOfShape *theGroups,
+ Standard_Boolean &IsDoSides)
+{
+ const TopoDS_Shape aDownShape = theSweep->FirstShape();
+ const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
+ TopAbs_ShapeEnum anUpDownType = TopAbs_SHAPE;
+
+ IsDoSides = Standard_False;
+
+ switch (aType) {
+ case TopAbs_EDGE:
+ case TopAbs_WIRE:
+ anUpDownType = TopAbs_EDGE;
+
+ if (GEOMUtils::IsOpenPath(aDownShape)) {
+ IsDoSides = Standard_True;
+ }
+ break;
+ case TopAbs_FACE:
+ case TopAbs_SHELL:
+ anUpDownType = TopAbs_FACE;
+ break;
+ default:
+ break;
+ }
+
+ if (anUpDownType == TopAbs_SHAPE) {
+ // Invalid Up and Down group type.
+ return false;
+ }
+
+ TopExp_Explorer anExp(aDownShape, anUpDownType);
+ TopTools_MapOfShape aMapFence;
+
+ // Create Down group.
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &aShape = anExp.Current();
+
+ if (aMapFence.Add(aShape)) {
+ theGroups[GROUP_DOWN].Append(aShape);
+ }
+ }
+
+ // Create Up group
+ const TopoDS_Shape anUpShape = theSweep->LastShape();
+
+ aMapFence.Clear();
+ anExp.Init(anUpShape, anUpDownType);
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &aShape = anExp.Current();
+
+ if (aMapFence.Add(aShape)) {
+ theGroups[GROUP_UP].Append(aShape);
+ }
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : DoGroups1
+//purpose : auxiliary for CreateGroups1()
+//=======================================================================
+bool DoGroups1 (const TopoDS_Shape &theProfile,
+ BRepOffsetAPI_MakePipeShell &theSweep,
+ TopTools_SequenceOfShape *theGroups)
+{
+ Standard_Boolean isDoSides = Standard_False;
+
+ if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
+ // Up and Down groups creation failure
+ return false;
+ }
+
+ TopoDS_Shape aDownShape = theProfile;
+ if (aDownShape.IsNull()) aDownShape = theSweep.FirstShape();
+
+ if (isDoSides) {
+ // Create Side1 and Side2 groups.
+ const TopAbs_ShapeEnum aType = aDownShape.ShapeType();
+ TopoDS_Vertex aV[2];
+ Standard_Integer i;
+
+ if (aType == TopAbs_EDGE) {
+ TopExp::Vertices(TopoDS::Edge(aDownShape), aV[0], aV[1], Standard_True);
+ } else { // aType == TopAbs_WIRE
+ TopExp::Vertices(TopoDS::Wire(aDownShape), aV[0], aV[1]);
+ }
+
+ for (i = 0; i < 2; ++i) {
+ if (aV[i].IsNull() == Standard_False) {
+ const TopTools_ListOfShape &aLstSide = theSweep.Generated(aV[i]);
+
+ if (!aLstSide.IsEmpty()) {
+ TopTools_ListIteratorOfListOfShape aSideIt(aLstSide);
+ TopTools_MapOfShape aMapFence;
+ const Standard_Integer anIdSide =
+ (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
+
+ for (; aSideIt.More(); aSideIt.Next()) {
+ const TopoDS_Shape &aSideShape = aSideIt.Value();
+
+ if (aSideShape.ShapeType() == TopAbs_EDGE) {
+ if (aMapFence.Add(aSideShape)) {
+ theGroups[anIdSide].Append(aSideShape);
+ }
+ } else if (aSideShape.ShapeType() == TopAbs_WIRE) {
+ if (aMapFence.Add(aSideShape)) {
+ TopExp_Explorer anExpWE (aSideShape, TopAbs_EDGE);
+ for (; anExpWE.More(); anExpWE.Next()) {
+ theGroups[anIdSide].Append(anExpWE.Current());
+ }
+ }
+ } else {
+ // Only edges can be in Side1 and Side2 groups.
+ return false;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // Create Other group. Get boundary edges of the profile.
+ TopTools_MapOfShape aMapBndEdges;
+ TopExp_Explorer anExp(aDownShape, TopAbs_EDGE);
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &anEdge = anExp.Current();
+
+ if (!aMapBndEdges.Add(anEdge)) {
+ aMapBndEdges.Remove(anEdge);
+ }
+ }
+
+ // Fill the map of faces generated from profile's boundary edges.
+ TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
+ TopTools_MapOfShape aMapFence;
+
+ for (; anIter.More(); anIter.Next()) {
+ const TopTools_ListOfShape &aLstOther = theSweep.Generated(anIter.Key());
+
+ if (!aLstOther.IsEmpty()) {
+ TopTools_ListIteratorOfListOfShape anOtherIt(aLstOther);
+
+ for (; anOtherIt.More(); anOtherIt.Next()) {
+ const TopoDS_Shape &anOtherShape = anOtherIt.Value();
+
+ if (anOtherShape.ShapeType() == TopAbs_FACE) {
+ if (aMapFence.Add(anOtherShape)) {
+ theGroups[GROUP_OTHER].Append(anOtherShape);
+ }
+ } else if (anOtherShape.ShapeType() == TopAbs_SHELL) {
+ if (aMapFence.Add(anOtherShape)) {
+ TopExp_Explorer anExpSHF (anOtherShape, TopAbs_FACE);
+ for (; anExpSHF.More(); anExpSHF.Next()) {
+ theGroups[GROUP_OTHER].Append(anExpSHF.Current());
+ }
+ }
+ } else {
+ // Only faces can be in Other group.
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : CreateGroups1
+//purpose : auxiliary for Execute()
+//=======================================================================
+bool CreateGroups1 (const TopoDS_Shape &theProfile,
+ BRepOffsetAPI_MakePipeShell &theSweep,
+ GEOMImpl_IPipe *theCI)
+{
+ if (!theCI->GetGenerateGroups()) {
+ // Nothing to do.
+ return true;
+ }
+
+ // Make groups.
+ TopTools_SequenceOfShape aGroups[5];
+
+ if (!DoGroups1(theProfile, theSweep, aGroups)) {
+ return false;
+ }
+
+ // Fill the groups.
+ Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+ TopTools_IndexedMapOfShape anIndices;
+ const TopoDS_Shape aResult = theSweep.Shape();
+
+ TopExp::MapShapes(aResult, anIndices);
+
+ if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+ return false;
+ }
+
+ // Store groups.
+ StoreGroups(theCI, aGroupIds);
+
+ return true;
+}
+
+//=======================================================================
+//function : DoGroups2
+//purpose : auxiliary for CreateGroups()
+//=======================================================================
+static bool DoGroups2(const TopoDS_Shape &theProfile,
+ const TopoDS_Shape &thePath,
+ BRepOffsetAPI_MakePipe &theSweep,
+ TopTools_SequenceOfShape *theGroups)
+{
+ Standard_Boolean isDoSides = Standard_False;
+
+ if (!CreateDownUpGroups(&theSweep, theGroups, isDoSides)) {
+ // Up and Down groups creation failure
+ return false;
+ }
+
+ if (isDoSides) {
+ // Create Side1 and Side2 groups.
+ const TopAbs_ShapeEnum aType = theProfile.ShapeType();
+ TopoDS_Vertex aV[2];
+ Standard_Integer i;
+
+ if (aType == TopAbs_EDGE) {
+ TopExp::Vertices(TopoDS::Edge(theProfile), aV[0], aV[1], Standard_True);
+ } else { // aType == TopAbs_WIRE
+ TopExp::Vertices(TopoDS::Wire(theProfile), aV[0], aV[1]);
+ }
+
+ for (i = 0; i < 2; ++i) {
+ if (aV[i].IsNull() == Standard_False) {
+ TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
+ TopTools_MapOfShape aMapFence;
+ const Standard_Integer anIdSide =
+ (i == 0 ? GROUP_SIDE1 : GROUP_SIDE2);
+
+ for (; anExpP.More(); anExpP.Next()) {
+ const TopoDS_Shape aSideShape =
+ theSweep.Generated(anExpP.Current(), aV[i]);
+
+ if (aSideShape.ShapeType() == TopAbs_EDGE) {
+ if (aMapFence.Add(aSideShape)) {
+ theGroups[anIdSide].Append(aSideShape);
+ }
+ } else {
+ // Only edges can be is Side1 and Side2 groups.
+ return false;
+ }
+ }
+ }
+ }
+ } else {
+ // Create Other group. Get boundary edges of the profile.
+ TopTools_MapOfShape aMapBndEdges;
+ TopExp_Explorer anExp(theProfile, TopAbs_EDGE);
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &anEdge = anExp.Current();
+
+ if (!aMapBndEdges.Add(anEdge)) {
+ aMapBndEdges.Remove(anEdge);
+ }
+ }
+
+ TopExp_Explorer anExpP(thePath, TopAbs_EDGE);
+ TopTools_MapOfShape aMapFence;
+
+ for (; anExpP.More(); anExpP.Next()) {
+ TopTools_MapIteratorOfMapOfShape anIter(aMapBndEdges);
+
+ for (; anIter.More(); anIter.Next()) {
+ const TopoDS_Shape anOtherShape =
+ theSweep.Generated(anExpP.Current(), anIter.Key());
+
+ if (anOtherShape.ShapeType() == TopAbs_FACE) {
+ if (aMapFence.Add(anOtherShape)) {
+ theGroups[GROUP_OTHER].Append(anOtherShape);
+ }
+ } else {
+ // Only faces can be in Other group.
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : CreateGroups
+//purpose : auxiliary for Execute()
+//=======================================================================
+static bool CreateGroups2(const TopoDS_Shape &theProfile,
+ const TopoDS_Shape &thePath,
+ BRepOffsetAPI_MakePipe &theSweep,
+ GEOMImpl_IPipe *theCI)
+{
+ if (!theCI->GetGenerateGroups()) {
+ // Nothing to do.
+ return true;
+ }
+
+ // Make groups.
+ TopTools_SequenceOfShape aGroups[5];
+
+ if (!DoGroups2(theProfile, thePath, theSweep, aGroups)) {
+ return false;
+ }
+
+ // Fill the groups.
+ Handle(TColStd_HArray1OfInteger) aGroupIds[5];
+ TopTools_IndexedMapOfShape anIndices;
+ const TopoDS_Shape aResult = theSweep.Shape();
+
+ TopExp::MapShapes(aResult, anIndices);
+
+ if (!FillGroups(aGroups, anIndices, aGroupIds)) {
+ return false;
+ }
+
+ // Store groups.
+ StoreGroups(theCI, aGroupIds);
+
+ return true;
+}
+
//=======================================================================
//function : Execute
//purpose :
//=======================================================================
-Standard_Integer GEOMImpl_PipeDriver::Execute (TFunction_Logbook& log) const
+Standard_Integer GEOMImpl_PipeDriver::Execute(Handle(TFunction_Logbook)& log) const
{
if (Label().IsNull()) return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
if (aCI) delete aCI;
Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
}
+
+ // Check if it is possible to create groups.
+ if (aCI->GetGenerateGroups() && !GEOMUtils::IsOpenPath(aWirePath)) {
+ if (aCI) {
+ delete aCI;
+ }
+
+ Standard_ConstructionError::Raise
+ ("Can't create groups if the path is closed");
+ }
}
- TopoDS_Shape aShape;
+ TopoDS_Shape aShape;
+ const Standard_Boolean isGenerateGroups = aCI->GetGenerateGroups();
if (aType == PIPE_BASE_PATH) {
Handle(GEOM_Function) aRefBase = aCI->GetBase();
if (aShapeBase.ShapeType() == TopAbs_EDGE ||
aShapeBase.ShapeType() == TopAbs_WIRE)
{
- TopoDS_Wire Profile;
+ TopoDS_Wire aProfile;
if (aShapeBase.ShapeType() == TopAbs_WIRE)
- Profile = TopoDS::Wire(aShapeBase);
+ aProfile = TopoDS::Wire(aShapeBase);
else
{
BRep_Builder BB;
- BB.MakeWire(Profile);
- BB.Add(Profile, aShapeBase);
+ BB.MakeWire(aProfile);
+ BB.Add(aProfile, aShapeBase);
}
BRepOffsetAPI_MakePipeShell Sweep (aWirePath);
BRepBuilderAPI_MakeFace FaceBuilder (aWirePath, Standard_True); //to find the plane of spine
if (FaceBuilder.IsDone())
Sweep.SetMode(FaceBuilder.Face());
- Sweep.Add(Profile);
- Sweep.Build();
-
- if (!Sweep.IsDone())
+ Sweep.Add(aProfile);
+
+ Standard_Boolean isDone = BuildPipeShell(Sweep);
+
+ if (!isDone)
{
if (aCI) delete aCI;
Standard_ConstructionError::Raise("MakePipeShell failed");
}
else
aShape = Sweep.Shape(); //result is good
-
+
+ if (!CreateGroups1(aProfile, Sweep, aCI)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
}
else
{
GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
- aShape = BRepOffsetAPI_MakePipe(aWirePath, aShapeBase, theBestMode);
+ BRepOffsetAPI_MakePipe aMkPipe
+ (aWirePath, aShapeBase, theBestMode, Standard_True);
+
+ if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
+ aShape = aMkPipe.Shape();
+
+ if (!CreateGroups2(aShapeBase, aWirePath, aMkPipe, aCI)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+ } else if (theBestMode != GeomFill_IsDiscreteTrihedron) {
+ // Try to use Descrete Trihedron mode.
+ BRepOffsetAPI_MakePipe aMkPipeDescrete
+ (aWirePath, aShapeBase, GeomFill_IsDiscreteTrihedron, Standard_True);
+
+ if (aMkPipeDescrete.IsDone()) {
+ aShape = aMkPipeDescrete.Shape();
+
+ if (!CreateGroups2(aShapeBase, aWirePath, aMkPipeDescrete, aCI)) {
+ if (aCI) delete aCI;
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+ }
+ }
}
}
Handle(TColStd_HSequenceOfTransient) aLocObjs = aCIDS->GetLocations ();
Standard_Boolean aWithContact = (aCIDS->GetWithContactMode());
Standard_Boolean aWithCorrect = (aCIDS->GetWithCorrectionMode());
+ Standard_Boolean isBySteps = aCIDS->GetIsBySteps();
+
if (aCI) {
delete aCI;
aCI = 0;
aHSeqLocs->Append(aShapeLoc);
}
- aShape = CreatePipeWithDifferentSections(aWirePath, aHSeqBases, aHSeqLocs, aWithContact, aWithCorrect);
+
+ Handle(TColStd_HArray1OfInteger) *pGroups = NULL;
+ Handle(TColStd_HArray1OfInteger) aGroups[5];
+
+ if (isGenerateGroups) {
+ pGroups = aGroups;
+ }
+
+ aShape = CreatePipeWithDifferentSections
+ (aWirePath, aHSeqBases, aHSeqLocs,
+ aWithContact, aWithCorrect, isBySteps, pGroups);
+
+ if (isGenerateGroups) {
+ // Store created groups.
+ GEOMImpl_IPipeDiffSect aPipeDS(aFunction);
+
+ StoreGroups(&aPipeDS, aGroups);
+ }
}
//building pipe with shell sections
if (aShape.IsNull()) return 0;
- BRepCheck_Analyzer ana (aShape, Standard_False);
- if (!ana.IsValid()) {
- ShapeFix_ShapeTolerance aSFT;
- aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
- Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
- aSfs->SetPrecision(Precision::Confusion());
- aSfs->Perform();
- aShape = aSfs->Shape();
-
- ana.Init(aShape, Standard_False);
- if (!ana.IsValid())
- Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
- }
+ if ( !GEOMUtils::CheckShape(aShape) && !GEOMUtils::FixShapeTolerance(aShape) )
+ Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
if (aType != PIPE_BASE_PATH &&
aType != PIPE_SHELLS_WITHOUT_PATH) {
aVertMaxTol = aTol;
}
aVertMaxTol += Precision::Confusion();
- aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, aVertMaxTol, Standard_True);
- //aShape = GEOMImpl_GlueDriver::GlueFaces(aShape, Precision::Confusion(), Standard_True);
+
+ TopTools_DataMapOfShapeListOfShape aMapModif;
+ TopTools_DataMapOfShapeListOfShape *pMapModif = NULL;
+
+ if (isGenerateGroups) {
+ pMapModif = &aMapModif;
+ }
+
+ TopoDS_Shape aNewShape = GEOMImpl_GlueDriver::GlueFaces
+ (aShape, aVertMaxTol, Standard_True, pMapModif);
+
+ if (isGenerateGroups && !aMapModif.IsEmpty()) {
+ // Update groups.
+ GEOMImpl_IPipe aCI(aFunction);
+ Handle(TColStd_HArray1OfInteger) aGroupIDs[5] =
+ { aCI.GetGroupDown(), aCI.GetGroupUp(), aCI.GetGroupSide1(),
+ aCI.GetGroupSide2(), aCI.GetGroupOther() };
+ TopTools_IndexedMapOfShape anIndices;
+ TopTools_IndexedMapOfShape aNewIndices;
+ TopTools_SequenceOfShape aNewShapes[5];
+ TopTools_MapOfShape aMapReplaced;
+ TopTools_MapOfShape aMapGlued;
+ Standard_Integer iGrp;
+ Standard_Integer i;
+
+ TopExp::MapShapes(aShape, anIndices);
+ TopExp::MapShapes(aNewShape, aNewIndices);
+
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ if (aGroupIDs[iGrp].IsNull() == Standard_False) {
+ const Standard_Integer aLower = aGroupIDs[iGrp]->Lower();
+ const Standard_Integer anUpper = aGroupIDs[iGrp]->Upper();
+
+ for (i = aLower; i <= anUpper; ++i) {
+ const Standard_Integer anIndex = aGroupIDs[iGrp]->Value(i);
+ const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
+
+ if (aMapModif.IsBound(aSubShape)) {
+ const TopTools_ListOfShape &aListModif =
+ aMapModif.Find(aSubShape);
+ TopTools_ListIteratorOfListOfShape anIter(aListModif);
+
+ for (; anIter.More(); anIter.Next()) {
+ const TopoDS_Shape &aNewShape = anIter.Value();
+
+ if (aMapReplaced.Add(aNewShape)) {
+ aNewShapes[iGrp].Append(aNewShape);
+ } else {
+ // This is a glued shape. It means that it is internal
+ // one and should be removed from groups later.
+ aMapGlued.Add(aNewShape);
+ }
+ }
+ } else {
+ // Shape is not modified.
+ aNewShapes[iGrp].Append(aSubShape);
+ }
+ }
+ }
+ }
+
+ if (!aMapGlued.IsEmpty()) {
+ // Remove glued (internal) shapes from groups.
+ for (iGrp = 0; iGrp < 5; ++iGrp) {
+ Standard_Integer aNbShapes = aNewShapes[iGrp].Length();
+
+ for (i = 1; i < aNbShapes; ++i) {
+ const TopoDS_Shape &aNewShape = aNewShapes[iGrp].Value(i);
+
+ if (aMapGlued.Contains(aNewShape)) {
+ aNewShapes[iGrp].Remove(i);
+ --i;
+ --aNbShapes;
+ }
+ }
+ }
+ }
+
+ // Store modified groups.
+ Handle(TColStd_HArray1OfInteger) aNewGroupIDs[5];
+
+ if (!FillGroups(aNewShapes, aNewIndices, aNewGroupIDs)) {
+ Standard_ConstructionError::Raise("Generate groups failure");
+ }
+
+ StoreGroups(&aCI, aNewGroupIDs);
+ }
+
+ aShape = aNewShape;
}
}
+ // Note: group indices should not be changed after the next call.
TopoDS_Shape aRes = GEOMUtils::CompsolidToCompound(aShape);
aFunction->SetValue(aRes);
- log.SetTouched(Label());
+ log->SetTouched(Label());
return 1;
}
AddParam( theParams, "Bases", aCI.GetBases() );
AddParam( theParams, "Locations", aCI.GetLocations() );
AddParam( theParams, "Path", aCI.GetPath() );
- AddParam( theParams, "With contact", aCI.GetWithContactMode() );
- AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
+
+ if (!aCI.GetIsBySteps()) {
+ AddParam( theParams, "With contact", aCI.GetWithContactMode() );
+ AddParam( theParams, "With correction", aCI.GetWithCorrectionMode() );
+ }
+
+ AddParam( theParams, "Step by step", aCI.GetIsBySteps() );
break;
}
case PIPE_SHELL_SECTIONS:
return true;
}
-IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PipeDriver,GEOM_BaseDriver);
IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PipeDriver,GEOM_BaseDriver);