1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_Splitter.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMImpl_Gen.hxx"
43 #include "GEOMImpl_Types.hxx"
45 #include "GEOMImpl_IBasicOperations.hxx"
46 #include "GEOMImpl_IBooleanOperations.hxx"
47 #include "GEOMImpl_IShapesOperations.hxx"
48 #include "GEOMImpl_ITransformOperations.hxx"
49 #include "GEOMImpl_IBlocksOperations.hxx"
50 #include "GEOMImpl_I3DPrimOperations.hxx"
51 #include "GEOMImpl_ILocalOperations.hxx"
52 #include "GEOMImpl_IHealingOperations.hxx"
53 #include "GEOMImpl_IGroupOperations.hxx"
54 #include "GEOMImpl_GlueDriver.hxx"
56 #include <TDF_Tool.hxx>
57 #include <TFunction_DriverTable.hxx>
58 #include <TFunction_Driver.hxx>
59 #include <TFunction_Logbook.hxx>
60 #include <TNaming_CopyShape.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRepAlgoAPI_Cut.hxx>
75 #include <BRepAlgoAPI_Fuse.hxx>
76 #include <BRepBuilderAPI_MakeFace.hxx>
77 #include <BRepBuilderAPI_MakeVertex.hxx>
78 #include <BRepBuilderAPI_Transform.hxx>
79 #include <BRepPrimAPI_MakeCone.hxx>
80 #include <BRepPrimAPI_MakeCylinder.hxx>
86 #include <GC_MakeConicalSurface.hxx>
87 #include <Geom_CylindricalSurface.hxx>
89 #include <ShapeAnalysis_Edge.hxx>
93 #include "AdvancedEngine_Types.hxx"
95 #include <Standard_Stream.hxx>
96 #include <Standard_Failure.hxx>
97 #include <StdFail_NotDone.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
101 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
102 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
103 #define THICKNESS "Thickness" //"Epaisseur"
104 #define FLANGE "Flange" // "Collerette"
105 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
106 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
107 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
108 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
110 #define FIND_GROUPS_BY_POINTS 1
112 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
113 // VSR 30/12/2014: macro enabled
114 #define FILLET_FIX_TOLERANCE
116 //=============================================================================
120 //=============================================================================
121 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
122 GEOM_IOperations(theEngine, theDocID)
124 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
125 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
126 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
127 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
128 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
129 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
130 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
131 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
132 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
133 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
136 //=============================================================================
140 //=============================================================================
141 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
143 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
144 delete myBasicOperations;
145 delete myBooleanOperations;
146 delete myShapesOperations;
147 delete myTransformOperations;
148 delete myBlocksOperations;
149 delete my3DPrimOperations;
150 delete myLocalOperations;
151 delete myHealingOperations;
152 delete myGroupOperations;
155 //=============================================================================
159 //=============================================================================
160 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
161 Handle(GEOM_Object) theP1,
162 Handle(GEOM_Object) theP2,
163 Handle(GEOM_Object) theP3)
165 // Old Local Coordinates System oldLCS
167 gp_Pnt P1(-theL1, 0, 0);
168 gp_Pnt P2(theL1, 0, 0);
169 gp_Pnt P3(0, 0, theL2);
171 gp_Dir oldX(gp_Vec(P1, P2));
172 gp_Dir oldZ(gp_Vec(P0, P3));
173 gp_Ax3 oldLCS(P0, oldZ, oldX);
175 // New Local Coordinates System newLCS
176 double LocX, LocY, LocZ;
177 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
178 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
179 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
180 LocX = (newP1.X() + newP2.X()) / 2.;
181 LocY = (newP1.Y() + newP2.Y()) / 2.;
182 LocZ = (newP1.Z() + newP2.Z()) / 2.;
183 gp_Pnt newO(LocX, LocY, LocZ);
185 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
186 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
187 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
190 aTrsf.SetDisplacement(oldLCS, newLCS);
195 //=============================================================================
197 * CheckCompatiblePosition
200 //=============================================================================
201 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
202 Handle(GEOM_Object) theP1,
203 Handle(GEOM_Object) theP2,
204 Handle(GEOM_Object) theP3,
208 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
209 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
210 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
212 double d12 = P1.Distance(P2);
213 double d13 = P1.Distance(P3);
214 double d23 = P2.Distance(P3);
215 // double d2 = newO.Distance(P3);
217 if (Abs(d12) <= Precision::Confusion()) {
218 SetErrorCode("Junctions points P1 and P2 are identical");
221 if (Abs(d13) <= Precision::Confusion()) {
222 SetErrorCode("Junctions points P1 and P3 are identical");
225 if (Abs(d23) <= Precision::Confusion()) {
226 SetErrorCode("Junctions points P2 and P3 are identical");
231 double newL1 = 0.5 * d12;
232 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
234 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
236 if (fabs(newL1 - theL1) > Precision::Approximation()) {
237 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
238 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
239 // std::cerr << "theL1 = newL1" << std::endl;
243 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
249 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
251 if (fabs(newL2 - theL2) > Precision::Approximation()) {
252 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
253 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
257 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
267 //=============================================================================
269 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
271 //=============================================================================
272 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
273 double theR1, double theW1, double theL1,
274 double theR2, double theW2, double theL2,
275 double theH, double theW, double theRF,
276 Handle(TColStd_HSequenceOfTransient) theSeq,
281 if (theShape.IsNull()) return false;
283 TopoDS_Shape aShape = theShape->GetValue();
284 if (aShape.IsNull()) {
285 SetErrorCode("Shape is not defined");
289 gp_Trsf aTrsfInv = aTrsf.Inverted();
291 // int expectedGroups = 0;
292 // if (shapeType == TSHAPE_BASIC)
293 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
294 // expectedGroups = 10;
296 // expectedGroups = 11;
297 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
298 // expectedGroups = 12;
300 double aR1Ext = theR1 + theW1;
301 double aR2Ext = theR2 + theW2;
303 /////////////////////////
304 //// Groups of Faces ////
305 /////////////////////////
308 // Comment the following lines when GetInPlace bug is solved
310 // Workaround of GetInPlace bug
311 // Create a bounding box that fits the shape
312 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
313 aBox->GetLastFunction()->SetDescription("");
314 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
315 aBox->GetLastFunction()->SetDescription("");
316 // Apply transformation to box
317 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
318 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
319 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
321 // Get the shell of the box
322 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
323 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
324 aBox->GetLastFunction()->SetDescription("");
325 aShell->GetLastFunction()->SetDescription("");
326 // Get the common shapes between shell and shape
327 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
328 (theShape, aShell, 1, Standard_False); // MakeCommon
329 if (aCommonCompound.IsNull()) {
330 SetErrorCode(myBooleanOperations->GetErrorCode());
333 aCommonCompound->GetLastFunction()->SetDescription("");
334 // Explode the faces of common shapes => 3 faces
335 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
336 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
337 aCommonCompound->GetLastFunction()->SetDescription("");
338 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
340 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
341 std::list<Handle(GEOM_Object)> aFacesList;
342 for (int j = 1 ; j <= 4 ; j++) {
343 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
344 if (!aFace.IsNull()) {
345 aFace->GetLastFunction()->SetDescription("");
346 aFacesList.push_back(aFace);
349 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
350 if (!aCompoundOfFaces.IsNull()) {
351 aCompoundOfFaces->GetLastFunction()->SetDescription("");
352 aCompoundOfFacesList.push_back(aCompoundOfFaces);
356 if (aCompoundOfFacesList.size() == 3) {
357 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
359 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
360 aCompoundOfFacesList.pop_front();
361 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
362 aCompoundOfFacesList.pop_front();
367 // Uncomment the following lines when GetInPlace bug is solved
369 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
370 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
371 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
372 // aP1->GetLastFunction()->SetDescription("");
373 // aP2->GetLastFunction()->SetDescription("");
374 // aP3->GetLastFunction()->SetDescription("");
375 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
376 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
377 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
378 // aV1->GetLastFunction()->SetDescription("");
379 // aV2->GetLastFunction()->SetDescription("");
380 // aV3->GetLastFunction()->SetDescription("");
381 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
382 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
383 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
384 // aPln1->GetLastFunction()->SetDescription("");
385 // aPln2->GetLastFunction()->SetDescription("");
386 // aPln3->GetLastFunction()->SetDescription("");
388 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
389 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
390 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
391 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
392 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
393 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
394 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
395 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
396 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
400 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
401 if (junctionFaces1.IsNull())
402 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
403 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
404 if (!junctionFaces1.IsNull()) {
405 junctionFaces1->GetLastFunction()->SetDescription("");
406 junctionFaces1->SetName("JUNCTION_FACE_1");
407 theSeq->Append(junctionFaces1);
410 SetErrorCode("Junction face 1 not found");
411 // theSeq->Append(aPln1);
414 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
415 if (junctionFaces2.IsNull())
416 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
417 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
418 if (!junctionFaces2.IsNull()) {
419 junctionFaces2->GetLastFunction()->SetDescription("");
420 junctionFaces2->SetName("JUNCTION_FACE_2");
421 theSeq->Append(junctionFaces2);
424 SetErrorCode("Junction face 2 not found");
425 // theSeq->Append(aPln2);
428 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
429 if (junctionFaces3.IsNull())
430 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
431 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
432 if (!junctionFaces3.IsNull()) {
433 junctionFaces3->GetLastFunction()->SetDescription("");
434 junctionFaces3->SetName("JUNCTION_FACE_3");
435 theSeq->Append(junctionFaces3);
438 SetErrorCode("Junction face 3 not found");
439 // theSeq->Append(aPln3);
442 // Comment the following lines when GetInPlace bug is solved
447 /////////////////////////
448 //// Groups of Edges ////
449 /////////////////////////
450 // Result of propagate
452 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
454 TCollection_AsciiString theDesc = aFunction->GetDescription();
455 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
456 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
457 SetErrorCode("Propagation groups not found");
460 Standard_Integer aNbGroups = aSeqPropagate->Length();
461 // Recover previous description to get rid of Propagate dump
462 aFunction->SetDescription(theDesc);
464 #ifdef FIND_GROUPS_BY_POINTS
465 // BEGIN: new groups search
472 // g / ''..| | |..'' \
474 // .---.--'.. | | | ..'--.---.
475 // |a \ '''...........''' / |
476 // |-------\------' | '------/-------.
481 // ._________________|_________________.
487 // |-----------------|-----------------|
489 // '-----------------'-----------------'
492 // "Thickness" group (a)
493 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
494 aPntA.Transform(aTrsf);
495 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
496 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
497 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
499 // "Circular quarter of pipe" group (b)
500 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
501 aPntB.Transform(aTrsf);
502 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
503 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
504 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
506 // "Circular quarter of pipe" group (c)
507 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
508 aPntC.Transform(aTrsf);
509 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
510 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
511 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
513 // "Main pipe half length" group (d)
514 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
515 aPntD.Transform(aTrsf);
516 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
517 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
518 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
520 // "Incident pipe half length" group (e)
521 double aTol10 = Precision::Confusion() * 10.;
522 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
523 aPntE.Transform(aTrsf);
524 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
525 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
526 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
528 // "Flange" group (f)
529 double aFx = - aR2Ext - aTol10;
530 if (shapeType == TSHAPE_CHAMFER)
532 else if (shapeType == TSHAPE_FILLET)
534 gp_Pnt aPntF (aFx, 0, aR1Ext);
535 aPntF.Transform(aTrsf);
536 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
537 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
538 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
540 // "Chamfer or Fillet" group (g)
541 TopoDS_Shape anEdgeG;
542 if (shapeType == TSHAPE_CHAMFER) {
543 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
544 aPntG.Transform(aTrsf);
545 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
546 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
547 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
549 else if (shapeType == TSHAPE_FILLET) {
550 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
551 aPntG.Transform(aTrsf);
552 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
553 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
554 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
557 for (int i = 1 ; i <= aNbGroups; i++) {
558 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
562 TopoDS_Shape aGroupShape = aGroup->GetValue();
563 TopTools_IndexedMapOfShape anEdgesMap;
564 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
566 if (anEdgesMap.Contains(anEdgeA)) { // a
567 aGroup->SetName("THICKNESS");
568 theSeq->Append(aGroup);
570 else if (anEdgesMap.Contains(anEdgeB)) { // b
571 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
572 theSeq->Append(aGroup);
574 else if (anEdgesMap.Contains(anEdgeC)) { // c
575 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
576 theSeq->Append(aGroup);
578 else if (anEdgesMap.Contains(anEdgeD)) { // d
579 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
580 theSeq->Append(aGroup);
582 else if (anEdgesMap.Contains(anEdgeE)) { // e
583 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
584 theSeq->Append(aGroup);
586 else if (anEdgesMap.Contains(anEdgeF)) { // f
587 aGroup->SetName("FLANGE");
588 theSeq->Append(aGroup);
590 else if (shapeType == TSHAPE_CHAMFER) { // g
591 if (anEdgesMap.Contains(anEdgeG)) {
592 aGroup->SetName("CHAMFER");
593 theSeq->Append(aGroup);
596 else if (shapeType == TSHAPE_FILLET) { // g
597 if (anEdgesMap.Contains(anEdgeG)) {
598 aGroup->SetName("FILLET");
599 theSeq->Append(aGroup);
605 // END: new groups search
608 bool circularFoundAndAdded = false;
609 bool circularFound10 = false;
610 bool incidentPipeFound = false;
611 bool mainPipeFound = false;
612 bool mainPipeFoundAndAdded = false;
613 bool radialFound =false;
614 bool flangeFound = false;
615 bool flangeFoundAndAdded = false;
616 bool chamferOrFilletFound = false;
618 for (int i = 1 ; i <= aNbGroups; i++) {
621 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
625 TopoDS_Shape aGroupShape = aGroup->GetValue();
626 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
627 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
629 TopTools_IndexedMapOfShape anEdgesMap;
630 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
631 Standard_Integer nbEdges = anEdgesMap.Extent();
633 if (shapeType == TSHAPE_BASIC) {
634 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
636 aGroup->SetName("THICKNESS");
638 else if (nbEdges == 6) {
639 if (!circularFoundAndAdded) {
640 circularFoundAndAdded = true;
642 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
645 else if (nbEdges == 8) {
646 incidentPipeFound = true;
647 mainPipeFound = false;
651 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
653 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
654 double x=aP.X(), y=aP.Y(), z=aP.Z();
657 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
658 (Abs(y) > aR2Ext + Precision::Confusion())) {
659 incidentPipeFound = false;
662 if ( z < -Precision::Confusion()) {
663 // length of main pipe
664 mainPipeFound = true;
665 if (!mainPipeFoundAndAdded) {
666 mainPipeFoundAndAdded = true;
668 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
672 else if (Abs(x) > (theL1-Precision::Confusion())) {
673 // discretisation circulaire
675 if (!circularFoundAndAdded) {
676 circularFoundAndAdded = true;
678 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
683 if (incidentPipeFound) {
685 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
687 if (!addGroup && (!incidentPipeFound &&
691 // Flange (collerette)
694 aGroup->SetName("FLANGE");
700 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
701 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
703 aGroup->SetName("THICKNESS");
705 else if ((nbEdges == 10) || (nbEdges == 6)) {
706 if (!circularFoundAndAdded) {
708 circularFoundAndAdded = true;
709 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
711 circularFound10 = true;
714 else if (!circularFound10 && nbEdges == 10) {
715 circularFound10 = true;
717 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
720 else if (nbEdges == 8) {
721 incidentPipeFound = true;
722 mainPipeFound = true;
725 bool isNearZ0 = false;
726 bool isBelowZ0 = false;
728 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
730 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
731 double x=aP.X(), y=aP.Y(), z=aP.Z();
733 // tuy_princ_long_avant & tuy_princ_long_apres
734 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
735 // ((y <= aR1Ext + Precision::Confusion()) ||
736 // (y <= -(aR1Ext + Precision::Confusion())) ||
737 // (y <= theR1 + Precision::Confusion()) ||
738 // (y == -(theR1 + Precision::Confusion()))));
739 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
740 (fabs(y) > theR1 - Precision::Confusion() ||
741 fabs(y) < Precision::Confusion()));
744 mainPipeFound = false;
748 //if (z < Precision::Confusion() && !isMain) {
749 // flangeFound = true;
750 // if (!flangeFoundAndAdded) {
751 // flangeFoundAndAdded = true;
753 // aGroup->SetName("FLANGE");
756 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
757 if (z < - Precision::Confusion()) isBelowZ0 = true;
760 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
761 (Abs(y) > aR2Ext + Precision::Confusion())) {
762 incidentPipeFound = false;
768 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
770 if (incidentPipeFound) {
772 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
774 if (isNearZ0 && !isBelowZ0) {
776 if (!flangeFoundAndAdded) {
777 flangeFoundAndAdded = true;
779 aGroup->SetName("FLANGE");
782 if (!addGroup && (!incidentPipeFound &&
785 !chamferOrFilletFound)) {
787 chamferOrFilletFound = true;
788 if (shapeType == TSHAPE_CHAMFER)
789 aGroup->SetName("CHAMFER");
791 aGroup->SetName("FILLET");
797 // Add group to the list
799 theSeq->Append(aGroup);
807 //=============================================================================
809 * Return faces that are laying on surface.
811 //=============================================================================
812 bool AdvancedEngine_IOperations::GetFacesOnSurf
813 (const TopoDS_Shape &theShape,
814 const Handle_Geom_Surface& theSurface,
815 const Standard_Real theTolerance,
816 TopTools_ListOfShape &theFaces)
818 GEOMAlgo_FinderShapeOn1 aFinder;
820 aFinder.SetShape(theShape);
821 aFinder.SetTolerance(theTolerance);
822 aFinder.SetSurface(theSurface);
823 aFinder.SetShapeType(TopAbs_FACE);
824 aFinder.SetState(GEOMAlgo_ST_ON);
826 // Sets the minimal number of inner points for the faces that do not have own
827 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
829 aFinder.SetNbPntsMin(3);
830 // Sets the maximal number of inner points for edges or faces.
831 // It is usefull for the cases when this number is very big (e.g =2000) to improve
832 // the performance. If this value =0, all inner points will be taken into account.
834 aFinder.SetNbPntsMax(100);
837 // Interprete results
838 Standard_Integer iErr = aFinder.ErrorStatus();
839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
841 MESSAGE(" iErr : " << iErr);
842 TCollection_AsciiString aMsg (" iErr : ");
843 aMsg += TCollection_AsciiString(iErr);
847 Standard_Integer iWrn = aFinder.WarningStatus();
848 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
850 MESSAGE(" *** iWrn : " << iWrn);
853 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
854 TopTools_ListIteratorOfListOfShape anIter (aListRes);
856 for (; anIter.More(); anIter.Next()) {
857 theFaces.Append(anIter.Value());
863 //=============================================================================
865 * Creates and returns conical face.
867 //=============================================================================
868 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
869 (const gp_Ax2 &theAxis,
870 const double theRadius,
871 const double theRadiusThin,
872 const double theHeight,
873 const gp_Trsf &theTrsf)
875 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
876 TopoDS_Shape aResult;
879 if (aMkCone.IsDone()) {
880 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
882 for (; anExp.More(); anExp.Next()) {
883 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
885 if (aFace.IsNull() == Standard_False) {
886 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
888 if (anAdaptor.GetType() == GeomAbs_Cone) {
889 // This is a conical face. Transform and return it.
890 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
892 aResult = aTransf.Shape();
902 //=============================================================================
904 * Generate the internal group of a Pipe T-Shape
906 //=============================================================================
907 bool AdvancedEngine_IOperations::MakeInternalGroup
908 (const Handle(GEOM_Object) &theShape,
909 const double theR1, const double theLen1,
910 const double theR2, const double theLen2,
911 const double theRL, double theTransLenL,
912 const double theRR, double theTransLenR,
913 const double theRI, double theTransLenI,
914 const Handle(TColStd_HSequenceOfTransient) &theSeq,
915 const gp_Trsf &theTrsf)
919 if (theShape.IsNull()) {
923 TopoDS_Shape aShape = theShape->GetValue();
925 if (aShape.IsNull()) {
926 SetErrorCode("Shape is not defined");
931 Standard_Real aMaxTol = -RealLast();
932 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
934 for (; anExp.More(); anExp.Next()) {
935 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
937 if (aVertex.IsNull() == Standard_False) {
938 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
940 if (aTol > aMaxTol) {
946 // Construct internal surfaces.
947 Standard_Integer i = 0;
948 const Standard_Integer aMaxNbSurf = 5;
949 Handle(Geom_Surface) aSurface[aMaxNbSurf];
950 TopTools_ListOfShape aConicalFaces;
951 Standard_Real aTolConf = Precision::Confusion();
953 // 1. Construct the internal surface of main pipe.
954 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
955 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
957 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
959 // 2. Construct the internal surface of incident pipe.
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
962 // 3. Construct the internal surface of left reduction pipe.
963 if (theRL > aTolConf) {
964 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
966 if (theTransLenL > aTolConf) {
967 // 3.1. Construct the internal surface of left transition pipe.
968 gp_Pnt aPLeft (-theLen1, 0., 0.);
969 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
970 TopoDS_Shape aConeLeft =
971 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
973 if (aConeLeft.IsNull() == Standard_False) {
974 aConicalFaces.Append(aConeLeft);
979 // 4. Construct the internal surface of right reduction pipe.
980 if (theRR > aTolConf) {
981 // There is no need to construct another cylinder of the same radius. Skip it.
982 if (Abs(theRR - theRL) > aTolConf) {
983 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
986 if (theTransLenL > aTolConf) {
987 // 4.1. Construct the internal surface of right transition pipe.
988 gp_Pnt aPRight (theLen1, 0., 0.);
989 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
990 TopoDS_Shape aConeRight =
991 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
993 if (aConeRight.IsNull() == Standard_False) {
994 aConicalFaces.Append(aConeRight);
999 // 5. Construct the internal surface of incident reduction pipe.
1000 if (theRI > aTolConf) {
1001 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1003 if (theTransLenI > aTolConf) {
1004 // 5.1. Construct the internal surface of incident transition pipe.
1005 gp_Pnt aPInci (0., 0., theLen2);
1006 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1007 TopoDS_Shape aConeInci =
1008 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1010 if (aConeInci.IsNull() == Standard_False) {
1011 aConicalFaces.Append(aConeInci);
1016 // Get faces that are laying on cylindrical surfaces.
1017 TopTools_ListOfShape aFaces;
1018 gp_Trsf anInvTrsf = theTrsf.Inverted();
1020 for (i = 0; i < aMaxNbSurf; i++) {
1021 if (aSurface[i].IsNull()) {
1025 aSurface[i]->Transform(theTrsf);
1027 TopTools_ListOfShape aLocalFaces;
1029 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1034 // Check if the result contains outer cylinders.
1035 // It is required for main and incident pipes.
1036 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1038 while (anIter.More()) {
1039 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1040 Standard_Boolean isInside = Standard_False;
1042 // Get a vertex from this shape
1044 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1046 if (aVtx.IsNull() == Standard_False) {
1047 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1049 aPnt.Transform(anInvTrsf);
1052 // Check if the point is inside the main pipe.
1053 isInside = (Abs(aPnt.X()) <= theLen1);
1055 // Check if the point is inside the incident pipe.
1056 isInside = (aPnt.Z() <= theLen2);
1065 // Remove this face.
1066 aLocalFaces.Remove(anIter);
1071 aFaces.Append(aLocalFaces);
1074 // Get faces that are laying on conical faces.
1075 if (aConicalFaces.IsEmpty() == Standard_False) {
1076 Handle(GEOM_Object) aCone =
1077 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1078 Handle(GEOM_Function) aFunction =
1079 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1080 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1081 Handle(GEOM_Object) aConeFromShape;
1083 for (; aFIter.More(); aFIter.Next()) {
1084 aFunction->SetValue(aFIter.Value());
1085 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1087 if (aConeFromShape.IsNull() == Standard_False) {
1088 aConeFromShape->GetLastFunction()->SetDescription("");
1089 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1090 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1092 for (; anExp.More(); anExp.Next()) {
1093 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1095 if (aConeFace.IsNull() == Standard_False) {
1096 aFaces.Append(aConeFace);
1103 // Create a group of internal faces.
1104 if (aFaces.IsEmpty() == Standard_False) {
1105 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1107 if (aGroup.IsNull() == Standard_False) {
1108 aGroup->GetLastFunction()->SetDescription("");
1109 aGroup->SetName("INTERNAL_FACES");
1111 TopTools_IndexedMapOfShape anIndices;
1112 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1114 TopExp::MapShapes(aShape, anIndices);
1116 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1118 for (; anIter.More(); anIter.Next()) {
1119 const TopoDS_Shape &aFace = anIter.Value();
1120 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1123 aSeqIDs->Append(anIndex);
1127 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1128 aGroup->GetLastFunction()->SetDescription("");
1129 theSeq->Append(aGroup);
1138 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1139 double theR1, double theW1, double theL1,
1140 double theR2, double theW2, double theL2,
1141 double theH, double theW,
1142 double theRF, bool isNormal)
1146 // Build tools for partition operation:
1147 // 1 face and 2 planes
1149 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1150 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1151 Handle(GEOM_Object) chan_racc;
1152 Handle(GEOM_Object) vi1, vi2;
1153 Handle(GEOM_Object) Te3;
1157 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1158 Vector_Z->GetLastFunction()->SetDescription("");
1161 double aSize = 2*(theL1 + theL2);
1162 double aR1Ext = theR1 + theW1;
1163 double aR2Ext = theR2 + theW2;
1164 double theVertCylinderRadius = aR2Ext + theW + theRF;
1165 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1167 // Common edges on internal cylinder
1168 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1169 box_i->GetLastFunction()->SetDescription("");
1170 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1171 box_i->GetLastFunction()->SetDescription("");
1173 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1174 TCollection_AsciiString theDesc = aFunction->GetDescription();
1175 Handle(TColStd_HSequenceOfTransient) edges_i =
1176 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1177 // Recover previous description to get rid of Propagate dump
1178 aFunction->SetDescription(theDesc);
1179 if (edges_i.IsNull() || edges_i->Length() == 0) {
1180 SetErrorCode("Internal edges not found");
1183 for (int i=1; i<=edges_i->Length();i++) {
1184 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1185 anObj->GetLastFunction()->SetDescription("");
1187 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1189 // search for vertices located on both internal pipes
1190 aFunction = theShape->GetLastFunction();
1191 theDesc = aFunction->GetDescription();
1192 Handle(TColStd_HSequenceOfTransient) vertices_i =
1193 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1194 // Recover previous description to get rid of Propagate dump
1195 aFunction->SetDescription(theDesc);
1196 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1197 SetErrorCode("Internal vertices not found");
1201 double d1min = theR2+theW2, d2min=theR2+theW2;
1202 for (int i = 1; i <= vertices_i->Length(); i++) {
1203 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1204 v->GetLastFunction()->SetDescription("");
1205 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1206 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1207 if (Abs(aP.X()) <= Precision::Confusion()) {
1208 if (Abs(aP.Y()) < d1min) {
1210 d1min = Abs(aP.Y());
1212 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1213 if (Abs(aP.X()) < d2min) {
1215 d2min = Abs(aP.X());
1219 if (vi1.IsNull() || vi2.IsNull()) {
1220 SetErrorCode("Cannot find internal intersection vertices");
1224 std::list<Handle(GEOM_Object)> theShapes;
1227 Handle(GEOM_Object) ve1, ve2;
1228 TopoDS_Vertex vertex1, vertex2;
1230 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1231 box_e->GetLastFunction()->SetDescription("");
1232 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1233 box_e->GetLastFunction()->SetDescription("");
1235 // search for vertices located on both external pipes
1236 aFunction = theShape->GetLastFunction();
1237 theDesc = aFunction->GetDescription();
1238 Handle(TColStd_HSequenceOfTransient) vertices_e =
1239 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1240 // Recover previous description to get rid of Propagate dump
1241 aFunction->SetDescription(theDesc);
1242 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1243 SetErrorCode("External vertices not found");
1247 double d1max = 0, d2max = 0;
1248 for (int i = 1; i <= vertices_e->Length(); i++) {
1249 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1250 v->GetLastFunction()->SetDescription("");
1251 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1252 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1253 if (Abs(aP.X()) <= Precision::Confusion()) {
1254 if (Abs(aP.Y()) > d1max) {
1257 d1max = Abs(aP.Y());
1259 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1260 if (Abs(aP.X()) > d2max) {
1263 d2max = Abs(aP.X());
1267 if (ve1.IsNull() || ve2.IsNull()) {
1268 SetErrorCode("Cannot find external intersection vertices");
1271 Handle(GEOM_Object) edge_e1, edge_e2;
1273 // Common edges on external cylinder
1274 aFunction = theShape->GetLastFunction();
1275 theDesc = aFunction->GetDescription();
1276 Handle(TColStd_HSequenceOfTransient) edges_e =
1277 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1278 // Recover previous description to get rid of Propagate dump
1279 aFunction->SetDescription(theDesc);
1280 if (edges_e.IsNull() || edges_e->Length() == 0) {
1281 SetErrorCode("External edges not found");
1284 ShapeAnalysis_Edge sae;
1285 for (int i=1; i<=edges_e->Length();i++) {
1286 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1287 anObj->GetLastFunction()->SetDescription("");
1288 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1289 if ( !anEdge.IsNull() &&
1290 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1291 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1292 arete_intersect_ext = anObj;
1296 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1297 if (edge_e1.IsNull()) {
1298 SetErrorCode("Edge 1 could not be built");
1302 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1303 if (edge_e2.IsNull()) {
1304 SetErrorCode("Edge 2 could not be built");
1308 edge_e1->GetLastFunction()->SetDescription("");
1309 edge_e2->GetLastFunction()->SetDescription("");
1311 std::list<Handle(GEOM_Object)> edge_e_elist;
1312 edge_e_elist.push_back(arete_intersect_int);
1313 edge_e_elist.push_back(edge_e1);
1314 edge_e_elist.push_back(arete_intersect_ext);
1315 edge_e_elist.push_back(edge_e2);
1316 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1317 if (wire_t.IsNull()) {
1318 SetErrorCode("Impossible to build wire");
1321 wire_t->GetLastFunction()->SetDescription("");
1322 face_t = myShapesOperations->MakeFace(wire_t, false);
1323 if (face_t.IsNull()) {
1324 SetErrorCode("Impossible to build face");
1327 face_t->GetLastFunction()->SetDescription("");
1329 theShapes.push_back(theShape);
1330 theShapes.push_back(vi1);
1331 theShapes.push_back(vi2);
1332 theShapes.push_back(ve1);
1333 theShapes.push_back(ve2);
1334 theShapes.push_back(edge_e1);
1335 theShapes.push_back(edge_e2);
1336 theShapes.push_back(wire_t);
1337 theShapes.push_back(face_t);
1340 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1341 int idP1, idP2, idP3, idP4;
1344 std::vector<int> LX;
1345 std::vector<int> LY;
1346 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1347 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1348 box_e->GetLastFunction()->SetDescription("");
1349 box_e = myTransformOperations->TranslateDXDYDZ
1350 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1351 box_e->GetLastFunction()->SetDescription("");
1353 aFunction = theShape->GetLastFunction();
1354 theDesc = aFunction->GetDescription();
1355 Handle(TColStd_HSequenceOfTransient) extremVertices =
1356 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1357 // Recover previous description to get rid of Propagate dump
1358 aFunction->SetDescription(theDesc);
1360 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1362 SetErrorCode("Vertices on chamfer not found");
1364 SetErrorCode("Vertices on fillet not found");
1368 theShapes.push_back(theShape);
1369 theShapes.push_back(box_e);
1370 if (extremVertices->Length() != 6) {
1371 // for (int i=1; i<=extremVertices->Length(); i++){
1372 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1374 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1375 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1376 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1377 SetErrorCode("Bad number of vertices on chamfer found");
1381 for (int i=1; i<=extremVertices->Length(); i++){
1382 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1383 aV->GetLastFunction()->SetDescription("");
1384 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1386 if (Abs(aP.X()) <= Precision::Confusion()) {
1387 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1389 if (aP.Z()-ZX > Precision::Confusion()) {
1396 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1398 if (aP.Z() - ZY > Precision::Confusion()) {
1409 if (LX.at(0) == PZX)
1412 if (LY.at(0) == PZY)
1415 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1416 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1417 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1418 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1420 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1421 if (Cote_1.IsNull()) {
1422 SetErrorCode("Impossible to build edge in thickness");
1425 Cote_1->GetLastFunction()->SetDescription("");
1427 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1428 if (Cote_2.IsNull()) {
1429 SetErrorCode("Impossible to build edge in thickness");
1432 Cote_2->GetLastFunction()->SetDescription("");
1434 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1435 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1436 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1437 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1438 if (edge_chan_princ.IsNull()) {
1439 SetErrorCode("Impossible to find edge on main pipe");
1442 edge_chan_princ->GetLastFunction()->SetDescription("");
1444 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1445 if (edge_chan_inc.IsNull()) {
1446 SetErrorCode("Impossible to find edge on incident pipe");
1449 edge_chan_inc->GetLastFunction()->SetDescription("");
1451 std::list<Handle(GEOM_Object)> edgeList1;
1452 edgeList1.push_back(edge_chan_princ);
1453 edgeList1.push_back(Cote_1);
1454 edgeList1.push_back(arete_intersect_int);
1455 edgeList1.push_back(Cote_2);
1457 // std::cerr << "Creating wire 1" << std::endl;
1458 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1459 if (wire_t.IsNull()) {
1460 SetErrorCode("Impossible to build wire");
1463 wire_t->GetLastFunction()->SetDescription("");
1465 // std::cerr << "Creating face 1" << std::endl;
1466 face_t = myShapesOperations->MakeFace(wire_t, false);
1467 if (face_t.IsNull()) {
1468 SetErrorCode("Impossible to build face");
1471 face_t->GetLastFunction()->SetDescription("");
1472 theShapes.push_back(face_t);
1474 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1475 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1476 double deltaZ = aP2.Z() - aP5.Z();
1477 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1478 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1479 if (P5bis.IsNull()) {
1480 SetErrorCode("Impossible to translate vertex");
1483 P5bis->GetLastFunction()->SetDescription("");
1485 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1486 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1487 deltaZ = aP4.Z() - aP6.Z();
1488 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1489 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1490 if (P6bis.IsNull()) {
1491 SetErrorCode("Impossible to translate vertex");
1494 P6bis->GetLastFunction()->SetDescription("");
1496 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1497 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1498 if (Cote_3.IsNull()) {
1499 SetErrorCode("Impossible to build edge in thickness");
1502 Cote_3->GetLastFunction()->SetDescription("");
1504 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1505 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1506 if (Cote_4.IsNull()) {
1507 SetErrorCode("Impossible to build edge in thickness");
1510 Cote_4->GetLastFunction()->SetDescription("");
1512 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1513 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1514 if (Cote_4.IsNull()) {
1515 SetErrorCode("Impossible to build edge in thickness");
1518 Cote_5->GetLastFunction()->SetDescription("");
1520 //std::list<Handle(GEOM_Object)> edgeList2;
1521 //edgeList2.push_back(edge_chan_inc);
1522 //edgeList2.push_back(Cote_3);
1523 //edgeList2.push_back(Cote_5);
1524 //edgeList2.push_back(Cote_4);
1525 // std::cerr << "Creating wire 2" << std::endl;
1526 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1527 //if (wire_t2.IsNull()) {
1528 // SetErrorCode("Impossible to build wire");
1531 //wire_t2->GetLastFunction()->SetDescription("");
1532 // std::cerr << "Creating face 2" << std::endl;
1533 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1535 // Mantis issue 0021682
1536 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1537 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1538 if (face_t2.IsNull()) {
1539 SetErrorCode("Impossible to build face");
1542 face_t2->GetLastFunction()->SetDescription("");
1543 theShapes.push_back(face_t2);
1547 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1548 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1549 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1550 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1551 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1552 aP0->GetLastFunction()->SetDescription("");
1553 aVZ->GetLastFunction()->SetDescription("");
1554 aVXZ->GetLastFunction()->SetDescription("");
1555 aPlnOZ->GetLastFunction()->SetDescription("");
1556 aPlnOXZ->GetLastFunction()->SetDescription("");
1557 theShapes.push_back(aPlnOZ);
1558 theShapes.push_back(aPlnOXZ);
1561 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1562 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1563 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1564 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1565 Handle(TColStd_HArray1OfInteger) theMaterials;
1567 partitionShapes->Append(theShape);
1568 theTools->Append(aPlnOZ);
1569 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1570 theTools->Append(aPlnOXZ);
1571 theTools->Append(face_t);
1573 theTools->Append(face_t2);
1575 Te3 = myBooleanOperations->MakePartition
1576 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1577 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1579 SetErrorCode("Impossible to build partition of TShape");
1582 Te3->GetLastFunction()->SetDescription("");
1584 // Last verification: result should be a block
1585 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1586 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1587 SetErrorCode("TShape is not a compound of block");
1591 // // BEGIN Compound of created shapes - Only for debug purpose
1592 // theShapes.clear();
1593 // theShapes.push_back(theShape);
1594 // theShapes.push_back(aPlnOZ);
1595 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1596 // theShapes.push_back(aPlnOXZ);
1597 // theShapes.push_back(face_t);
1599 // theShapes.push_back(face_t2);
1601 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1602 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1603 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1604 // // END Compound of created shapes - Only for debug purpose
1606 TopoDS_Shape aShape = Te3->GetValue();
1607 theShape->GetLastFunction()->SetValue(aShape);
1609 catch (Standard_Failure) {
1610 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1611 SetErrorCode(aFail->GetMessageString());
1619 // Mirror and glue faces
1620 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1621 double theR1, double theW1, double theL1,
1622 double theR2, double theW2, double theL2)
1627 double aSize = 2*(theL1 + theL2);
1628 double aR1Ext = theR1 + theW1;
1631 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1632 aP0->GetLastFunction()->SetDescription("");
1633 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1634 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1635 aVX->GetLastFunction()->SetDescription("");
1636 aVY->GetLastFunction()->SetDescription("");
1637 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1638 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1639 aPlane_OX->GetLastFunction()->SetDescription("");
1640 aPlane_OY->GetLastFunction()->SetDescription("");
1642 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1644 SetErrorCode("Impossible to build mirror of quarter TShape");
1648 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1650 SetErrorCode("Impossible to build mirror of half TShape");
1654 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1656 SetErrorCode("Impossible to build mirror of half TShape");
1660 std::list<Handle(GEOM_Object)> aShapesList;
1661 aShapesList.push_back(theShape);
1662 aShapesList.push_back(Te4);
1663 aShapesList.push_back(Te5);
1664 aShapesList.push_back(Te6);
1665 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1667 SetErrorCode("Impossible to build compound");
1671 // Copy source shape
1672 TopoDS_Shape aShapeCopy;
1673 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1674 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1676 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1678 SetErrorCode("Impossible to glue faces of TShape");
1682 TopoDS_Shape aShape = Te8->GetValue();
1683 BRepCheck_Analyzer anAna (aShape, Standard_True);
1685 if (!anAna.IsValid()) {
1686 // Try to do gluing with the tolerance equal to maximal
1687 // tolerance of vertices of the source shape.
1688 Standard_Real aTolMax = -RealLast();
1690 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1691 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1692 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1694 if (aTol > aTolMax) {
1700 Te7->GetLastFunction()->SetValue(aShapeCopy);
1701 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1704 SetErrorCode("Impossible to glue faces of TShape");
1708 aShape = Te8->GetValue();
1712 theShape->GetLastFunction()->SetValue(aShape);
1714 Te4->GetLastFunction()->SetDescription("");
1715 Te5->GetLastFunction()->SetDescription("");
1716 Te6->GetLastFunction()->SetDescription("");
1717 Te7->GetLastFunction()->SetDescription("");
1718 Te8->GetLastFunction()->SetDescription("");
1724 //=======================================================================
1725 //function : MakePipeTShapeThicknessReduction
1726 //purpose : Static method. Add thiskness reduction elements at the three
1727 // open ends of the T-Shape.
1728 //=======================================================================
1729 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1730 (TopoDS_Shape theShape,
1731 double r1, double w1, double l1,
1732 double r2, double w2, double l2,
1733 double rL, double wL, double ltransL, double lthinL,
1734 double rR, double wR, double ltransR, double lthinR,
1735 double rI, double wI, double ltransI, double lthinI,
1736 bool fuseReductions)
1738 // Add thickness reduction elements
1739 // at the three extremities: Left, Right and Incident
1741 // ---------------------.
1743 // ---------------------. \
1744 // ^ \ '-----------------.
1746 // | '-----------------'
1748 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1751 TopoDS_Shape aResult = theShape;
1752 double aTol = Precision::Confusion();
1754 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1756 // Left reduction (rL, wL, ltransL, lthinL)
1757 if (rL > aTol && wL > aTol && ltransL > aTol) {
1758 gp_Pnt aPLeft (-l1, 0, 0);
1759 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1760 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1761 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1763 if (fuseReductions) {
1764 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1765 if (!fuseL.IsDone())
1766 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1767 aResult = fuseL.Shape();
1774 B.Add(C, aReductionLeft);
1780 if (rR > aTol && wR > aTol && ltransR > aTol) {
1781 gp_Pnt aPRight (l1, 0, 0);
1782 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1783 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1784 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1786 if (fuseReductions) {
1787 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1788 if (!fuseR.IsDone())
1789 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1790 aResult = fuseR.Shape();
1797 B.Add(C, aReductionRight);
1802 // Incident reduction
1803 if (rI > aTol && wI > aTol && ltransI > aTol) {
1804 gp_Pnt aPInci (0, 0, l2);
1805 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1806 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1807 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1809 if (fuseReductions) {
1810 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1811 if (!fuseInci.IsDone())
1812 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1813 aResult = fuseInci.Shape();
1820 B.Add(C, aReductionInci);
1825 // Get rid of extra compounds
1826 TopTools_ListOfShape listShapeRes;
1827 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1828 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1830 if (!fuseReductions && listShapeRes.Extent() > 1) {
1831 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1836 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1837 for (; itSub.More(); itSub.Next())
1838 B.Add(C, itSub.Value());
1841 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1847 //=======================================================================
1848 //function : MakeThicknessReduction
1849 //purpose : Static method. Create one thickness reduction element.
1850 //=======================================================================
1851 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1852 const double R, const double W,
1853 const double Rthin, const double Wthin,
1854 const double Ltrans, const double Lthin,
1857 double aTol = Precision::Confusion();
1858 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1859 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1861 bool isThinPart = (Lthin > aTol);
1866 // ^ \ '-----------------.
1868 // | '-----------------'
1870 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1873 double RExt = R + W;
1874 double RthinExt = Rthin + Wthin;
1876 gp_Dir aNormal = theAxes.Direction();
1877 gp_Dir anXDir = theAxes.XDirection();
1878 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1879 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1881 // Build the transition part
1882 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1883 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1886 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1887 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1888 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1890 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1891 TopoDS_Shape aReduction = cut1.Shape();
1893 // Build the thin part, if required
1894 TopoDS_Shape aThinPart;
1896 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1897 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1900 if (!CExt.IsDone() || !CInt.IsDone())
1901 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1902 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1904 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1905 aThinPart = cut2.Shape();
1911 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1912 if (!fuse1.IsDone())
1913 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1914 aReduction = fuse1.Shape();
1918 // Partition the reduction on blocks
1919 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1920 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1921 gp_Pln aPln1 (anAxesPln1);
1922 gp_Pln aPln2 (anAxesPln2);
1923 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1924 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1925 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1927 GEOMAlgo_Splitter PS;
1928 PS.AddArgument(aReduction);
1930 PS.AddArgument(aThinPart);
1933 PS.SetLimit(TopAbs_SOLID);
1936 aReduction = PS.Shape();
1942 //=============================================================================
1945 * \brief Create a T-shape object with specified caracteristics for the main and
1946 * the incident pipes (radius, width, half-length).
1947 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1948 * \param theR1 Internal radius of main pipe
1949 * \param theW1 Width of main pipe
1950 * \param theL1 Half-length of main pipe
1951 * \param theR2 Internal radius of incident pipe (R2 < R1)
1952 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1953 * \param theL2 Half-length of incident pipe
1954 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1955 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1957 //=============================================================================
1958 Handle(TColStd_HSequenceOfTransient)
1959 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1960 double theR2, double theW2, double theL2,
1961 double theRL, double theWL, double theLtransL, double theLthinL,
1962 double theRR, double theWR, double theLtransR, double theLthinR,
1963 double theRI, double theWI, double theLtransI, double theLthinI,
1966 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1969 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1971 //Add a new shape function with parameters
1972 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1973 if (aFunction.IsNull()) return NULL;
1975 //Check if the function is set correctly
1976 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1978 AdvancedEngine_IPipeTShape aData (aFunction);
1986 aData.SetHexMesh(theHexMesh);
1988 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1989 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1990 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1992 //Compute the resulting value
1995 if (!GetSolver()->ComputeFunction(aFunction)) {
1996 SetErrorCode("TShape driver failed");
2001 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2003 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2007 if (isTRL || isTRR || isTRI) {
2008 // Add thickness reduction elements
2009 // at the three extremities: Left, Right and Incident
2010 TopoDS_Shape aResShape =
2011 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2012 theRL, theWL, theLtransL, theLthinL,
2013 theRR, theWR, theLtransR, theLthinR,
2014 theRI, theWI, theLtransI, theLthinI,
2016 aFunction->SetValue(aResShape);
2019 catch (Standard_Failure) {
2020 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2021 SetErrorCode(aFail->GetMessageString());
2025 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2026 aSeq->Append(aShape);
2031 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2032 0., 0., 0., aSeq, gp_Trsf()))
2036 // Get internal group.
2037 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2038 theRR, theLtransR, theRI, theLtransI,
2043 catch (Standard_Failure) {
2044 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2045 SetErrorCode(aFail->GetMessageString());
2049 //Make a Python command
2050 TCollection_AsciiString anEntry, aListRes("[");
2051 // Iterate over the sequence aSeq
2052 Standard_Integer aNbGroups = aSeq->Length();
2053 Standard_Integer i = 1;
2054 for (; i <= aNbGroups; i++) {
2055 Handle(Standard_Transient) anItem = aSeq->Value(i);
2056 if (anItem.IsNull()) continue;
2057 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2058 if (aGroup.IsNull()) continue;
2059 //Make a Python command
2060 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2061 aListRes += anEntry + ", ";
2063 aListRes.Trunc(aListRes.Length() - 2);
2065 GEOM::TPythonDump pd (aFunction);
2067 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2068 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2069 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2072 // thickness reduction
2074 pd << ", theRL=" << theRL << ", theWL=" << theWL
2075 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2077 pd << ", theRR=" << theRR << ", theWR=" << theWR
2078 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2080 pd << ", theRI=" << theRI << ", theWI=" << theWI
2081 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2090 //=============================================================================
2092 * MakePipeTShapeWithPosition
2093 * Create a T-shape object with specified caracteristics for the main and
2094 * the incident pipes (radius, width, half-length).
2095 * The extremities of the main pipe are located on junctions points P1 and P2.
2096 * The extremity of the incident pipe is located on junction point P3.
2097 * \param theR1 Internal radius of main pipe
2098 * \param theW1 Width of main pipe
2099 * \param theL1 Half-length of main pipe
2100 * \param theR2 Internal radius of incident pipe (R2 < R1)
2101 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2102 * \param theL2 Half-length of incident pipe
2103 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2104 * \param theP1 1st junction point of main pipe
2105 * \param theP2 2nd junction point of main pipe
2106 * \param theP3 Junction point of incident pipe
2107 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2109 //=============================================================================
2110 Handle(TColStd_HSequenceOfTransient)
2111 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2112 (double theR1, double theW1, double theL1,
2113 double theR2, double theW2, double theL2,
2114 double theRL, double theWL, double theLtransL, double theLthinL,
2115 double theRR, double theWR, double theLtransR, double theLthinR,
2116 double theRI, double theWI, double theLtransI, double theLthinI,
2118 Handle(GEOM_Object) theP1,
2119 Handle(GEOM_Object) theP2,
2120 Handle(GEOM_Object) theP3)
2124 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2128 //Add a new shape function with parameters
2129 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2130 if (aFunction.IsNull()) return NULL;
2132 //Check if the function is set correctly
2133 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2135 // Check new position
2136 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2140 AdvancedEngine_IPipeTShape aData(aFunction);
2148 aData.SetHexMesh(theHexMesh);
2150 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2151 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2152 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2154 //Compute the resulting value
2157 if (!GetSolver()->ComputeFunction(aFunction)) {
2158 SetErrorCode("TShape driver failed");
2163 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2165 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2169 if (isTRL || isTRR || isTRI) {
2170 // Add thickness reduction elements
2171 // at the three extremities: Left, Right and Incident
2172 TopoDS_Shape aResShape =
2173 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2174 theRL, theWL, theLtransL, theLthinL,
2175 theRR, theWR, theLtransR, theLthinR,
2176 theRI, theWI, theLtransI, theLthinI,
2178 aFunction->SetValue(aResShape);
2181 catch (Standard_Failure) {
2182 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2183 SetErrorCode(aFail->GetMessageString());
2187 TopoDS_Shape Te = aShape->GetValue();
2190 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2191 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2192 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2193 aFunction->SetValue(aTrsf_Shape);
2195 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2196 aSeq->Append(aShape);
2201 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2202 0., 0., 0., aSeq, aTrsf)) {
2207 // Get internal group.
2208 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2209 theRR, theLtransR, theRI, theLtransI,
2214 catch (Standard_Failure) {
2215 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2216 SetErrorCode(aFail->GetMessageString());
2220 //Make a Python command
2221 TCollection_AsciiString anEntry, aListRes("[");
2222 // Iterate over the sequence aSeq
2223 Standard_Integer aNbGroups = aSeq->Length();
2224 Standard_Integer i = 1;
2225 for (; i <= aNbGroups; i++) {
2226 Handle(Standard_Transient) anItem = aSeq->Value(i);
2227 if (anItem.IsNull()) continue;
2228 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2229 if (aGroup.IsNull()) continue;
2230 //Make a Python command
2231 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2232 aListRes += anEntry + ", ";
2234 aListRes.Trunc(aListRes.Length() - 2);
2236 GEOM::TPythonDump pd (aFunction);
2238 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2239 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2240 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2241 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2243 // thickness reduction
2245 pd << ", theRL=" << theRL << ", theWL=" << theWL
2246 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2248 pd << ", theRR=" << theRR << ", theWR=" << theWR
2249 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2251 pd << ", theRI=" << theRI << ", theWI=" << theWI
2252 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2261 //=============================================================================
2263 * MakePipeTShapeChamfer
2264 * Create a T-shape object with specified caracteristics for the main and
2265 * the incident pipes (radius, width, half-length). A chamfer is created
2266 * on the junction of the pipes.
2267 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2268 * \param theR1 Internal radius of main pipe
2269 * \param theW1 Width of main pipe
2270 * \param theL1 Half-length of main pipe
2271 * \param theR2 Internal radius of incident pipe (R2 < R1)
2272 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2273 * \param theL2 Half-length of incident pipe
2274 * \param theH Height of chamfer.
2275 * \param theW Width of chamfer.
2276 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2277 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2279 //=============================================================================
2280 Handle(TColStd_HSequenceOfTransient)
2281 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2282 (double theR1, double theW1, double theL1,
2283 double theR2, double theW2, double theL2,
2284 double theRL, double theWL, double theLtransL, double theLthinL,
2285 double theRR, double theWR, double theLtransR, double theLthinR,
2286 double theRI, double theWI, double theLtransI, double theLthinI,
2287 double theH, double theW,
2292 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2293 //Add a new shape function with parameters
2294 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2295 if (aFunction.IsNull()) return NULL;
2297 //Check if the function is set correctly
2298 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2300 AdvancedEngine_IPipeTShape aData(aFunction);
2310 aData.SetHexMesh(theHexMesh);
2312 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2313 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2314 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2316 //Compute the resulting value
2319 if (!GetSolver()->ComputeFunction(aFunction)) {
2320 SetErrorCode("TShape driver failed");
2324 catch (Standard_Failure) {
2325 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2326 SetErrorCode(aFail->GetMessageString());
2331 TopoDS_Shape aShapeShape = aShape->GetValue();
2332 TopTools_IndexedMapOfShape anEdgesIndices;
2333 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2334 // Common edges on external cylinders
2335 Handle(GEOM_Object) box_e;
2337 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2340 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2342 box_e->GetLastFunction()->SetDescription("");
2343 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2344 box_e->GetLastFunction()->SetDescription("");
2346 Handle(TColStd_HSequenceOfInteger) edges_e =
2347 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2348 box_e->GetLastFunction()->SetDescription("");
2350 if (edges_e.IsNull() || edges_e->Length() == 0) {
2351 SetErrorCode("External edges not found");
2354 int nbEdgesInChamfer = 0;
2355 std::list<int> theEdges;
2356 for (int i=1; i<=edges_e->Length();i++) {
2357 int edgeID = edges_e->Value(i);
2358 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2359 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2363 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2364 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2365 nbEdgesInChamfer ++;
2366 theEdges.push_back(edgeID);
2370 if (theHexMesh && nbEdgesInChamfer == 1)
2373 Handle(GEOM_Object) aChamfer;
2375 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2377 catch (Standard_Failure) {
2378 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2379 SetErrorCode(aFail->GetMessageString());
2382 if (aChamfer.IsNull()) {
2383 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2386 aChamfer->GetLastFunction()->SetDescription("");
2388 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2389 aFunction->SetValue(aChamferShape);
2393 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2395 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2399 // Add thickness reduction elements
2400 // at the three extremities: Left, Right and Incident
2403 if (isTRL || isTRR || isTRI) {
2404 TopoDS_Shape aResShape =
2405 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2406 theRL, theWL, theLtransL, theLthinL,
2407 theRR, theWR, theLtransR, theLthinR,
2408 theRI, theWI, theLtransI, theLthinI,
2410 aFunction->SetValue(aResShape);
2413 catch (Standard_Failure) {
2414 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2415 SetErrorCode(aFail->GetMessageString());
2419 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2420 aSeq->Append(aShape);
2425 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2426 theH, theW, 0., aSeq, gp_Trsf()))
2430 // Get internal group.
2431 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2432 theRR, theLtransR, theRI, theLtransI,
2437 catch (Standard_Failure) {
2438 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2439 SetErrorCode(aFail->GetMessageString());
2443 //Make a Python command
2444 TCollection_AsciiString anEntry, aListRes("[");
2445 // Iterate over the sequence aSeq
2446 Standard_Integer aNbGroups = aSeq->Length();
2447 Standard_Integer i = 1;
2448 for (; i <= aNbGroups; i++) {
2449 Handle(Standard_Transient) anItem = aSeq->Value(i);
2450 if (anItem.IsNull()) continue;
2451 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2452 if (aGroup.IsNull()) continue;
2453 //Make a Python command
2454 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2455 aListRes += anEntry + ", ";
2457 aListRes.Trunc(aListRes.Length() - 2);
2459 GEOM::TPythonDump pd (aFunction);
2461 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2462 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2463 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2464 << theH << ", " << theW << ", " << theHexMesh;
2466 // thickness reduction
2468 pd << ", theRL=" << theRL << ", theWL=" << theWL
2469 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2471 pd << ", theRR=" << theRR << ", theWR=" << theWR
2472 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2474 pd << ", theRI=" << theRI << ", theWI=" << theWI
2475 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2484 //=============================================================================
2486 * MakePipeTShapeChamferWithPosition
2487 * Create a T-shape object with specified caracteristics for the main and
2488 * the incident pipes (radius, width, half-length). A chamfer is created
2489 * on the junction of the pipes.
2490 * The extremities of the main pipe are located on junctions points P1 and P2.
2491 * The extremity of the incident pipe is located on junction point P3.
2492 * \param theR1 Internal radius of main pipe
2493 * \param theW1 Width of main pipe
2494 * \param theL1 Half-length of main pipe
2495 * \param theR2 Internal radius of incident pipe (R2 < R1)
2496 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2497 * \param theL2 Half-length of incident pipe
2498 * \param theH Height of chamfer.
2499 * \param theW Width of chamfer.
2500 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2501 * \param theP1 1st junction point of main pipe
2502 * \param theP2 2nd junction point of main pipe
2503 * \param theP3 Junction point of incident pipe
2504 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2506 //=============================================================================
2507 Handle(TColStd_HSequenceOfTransient)
2508 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2509 (double theR1, double theW1, double theL1,
2510 double theR2, double theW2, double theL2,
2511 double theRL, double theWL, double theLtransL, double theLthinL,
2512 double theRR, double theWR, double theLtransR, double theLthinR,
2513 double theRI, double theWI, double theLtransI, double theLthinI,
2514 double theH, double theW,
2516 Handle(GEOM_Object) theP1,
2517 Handle(GEOM_Object) theP2,
2518 Handle(GEOM_Object) theP3)
2522 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2523 //Add a new shape function with parameters
2524 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2525 if (aFunction.IsNull()) return NULL;
2527 //Check if the function is set correctly
2528 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2530 // Check new position
2531 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2535 AdvancedEngine_IPipeTShape aData(aFunction);
2545 aData.SetHexMesh(theHexMesh);
2547 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2548 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2549 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2551 //Compute the resulting value
2554 if (!GetSolver()->ComputeFunction(aFunction)) {
2555 SetErrorCode("TShape driver failed");
2559 catch (Standard_Failure) {
2560 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2561 SetErrorCode(aFail->GetMessageString());
2566 TopoDS_Shape aShapeShape = aShape->GetValue();
2567 TopTools_IndexedMapOfShape anEdgesIndices;
2568 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2569 // Common edges on external cylinders
2570 Handle(GEOM_Object) box_e;
2572 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2575 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2577 box_e->GetLastFunction()->SetDescription("");
2578 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2579 box_e->GetLastFunction()->SetDescription("");
2581 Handle(TColStd_HSequenceOfInteger) edges_e =
2582 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2583 box_e->GetLastFunction()->SetDescription("");
2585 if (edges_e.IsNull() || edges_e->Length() == 0) {
2586 SetErrorCode("External edges not found");
2589 int nbEdgesInChamfer = 0;
2590 std::list<int> theEdges;
2591 for (int i=1; i<=edges_e->Length();i++) {
2592 int edgeID = edges_e->Value(i);
2593 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2594 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2596 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2597 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2598 nbEdgesInChamfer ++;
2599 theEdges.push_back(edgeID);
2603 if (theHexMesh && nbEdgesInChamfer == 1)
2606 Handle(GEOM_Object) aChamfer;
2608 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2610 catch (Standard_Failure) {
2611 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2612 SetErrorCode(aFail->GetMessageString());
2615 if (aChamfer.IsNull()) {
2616 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2619 aChamfer->GetLastFunction()->SetDescription("");
2621 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2622 aFunction->SetValue(aChamferShape);
2626 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2628 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2632 // Add thickness reduction elements
2633 // at the three extremities: Left, Right and Incident
2636 if (isTRL || isTRR || isTRI) {
2637 TopoDS_Shape aResShape =
2638 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2639 theRL, theWL, theLtransL, theLthinL,
2640 theRR, theWR, theLtransR, theLthinR,
2641 theRI, theWI, theLtransI, theLthinI,
2643 aFunction->SetValue(aResShape);
2646 catch (Standard_Failure) {
2647 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2648 SetErrorCode(aFail->GetMessageString());
2653 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2654 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2655 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2656 aFunction->SetValue(aTrsf_Shape);
2658 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2659 aSeq->Append(aShape);
2664 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2665 theH, theW, 0., aSeq, aTrsf))
2669 // Get internal group.
2670 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2671 theRR, theLtransR, theRI, theLtransI,
2676 catch (Standard_Failure) {
2677 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2678 SetErrorCode(aFail->GetMessageString());
2682 //Make a Python command
2683 TCollection_AsciiString anEntry, aListRes("[");
2684 // Iterate over the sequence aSeq
2685 Standard_Integer aNbGroups = aSeq->Length();
2686 Standard_Integer i = 1;
2687 for (; i <= aNbGroups; i++) {
2688 Handle(Standard_Transient) anItem = aSeq->Value(i);
2689 if (anItem.IsNull()) continue;
2690 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2691 if (aGroup.IsNull()) continue;
2692 //Make a Python command
2693 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2694 aListRes += anEntry + ", ";
2696 aListRes.Trunc(aListRes.Length() - 2);
2698 GEOM::TPythonDump pd (aFunction);
2700 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2701 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2702 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2703 << theH << ", " << theW << ", " << theHexMesh << ", "
2704 << theP1 << ", " << theP2 << ", " << theP3;
2706 // thickness reduction
2708 pd << ", theRL=" << theRL << ", theWL=" << theWL
2709 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2711 pd << ", theRR=" << theRR << ", theWR=" << theWR
2712 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2714 pd << ", theRI=" << theRI << ", theWI=" << theWI
2715 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2724 //=============================================================================
2726 * MakePipeTShapeFillet
2727 * Create a T-shape object with specified caracteristics for the main and
2728 * the incident pipes (radius, width, half-length). A fillet is created
2729 * on the junction of the pipes.
2730 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2731 * \param theR1 Internal radius of main pipe
2732 * \param theW1 Width of main pipe
2733 * \param theL1 Half-length of main pipe
2734 * \param theR2 Internal radius of incident pipe (R2 < R1)
2735 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2736 * \param theL2 Half-length of incident pipe
2737 * \param theRF Radius of curvature of fillet.
2738 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2739 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2741 //=============================================================================
2742 Handle(TColStd_HSequenceOfTransient)
2743 AdvancedEngine_IOperations::MakePipeTShapeFillet
2744 (double theR1, double theW1, double theL1,
2745 double theR2, double theW2, double theL2,
2746 double theRL, double theWL, double theLtransL, double theLthinL,
2747 double theRR, double theWR, double theLtransR, double theLthinR,
2748 double theRI, double theWI, double theLtransI, double theLthinI,
2749 double theRF, bool theHexMesh)
2753 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2754 //Add a new shape function with parameters
2755 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2756 if (aFunction.IsNull()) return NULL;
2758 //Check if the function is set correctly
2759 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2761 AdvancedEngine_IPipeTShape aData(aFunction);
2770 aData.SetHexMesh(theHexMesh);
2772 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2773 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2774 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2776 //Compute the resulting value
2779 if (!GetSolver()->ComputeFunction(aFunction)) {
2780 SetErrorCode("TShape driver failed");
2784 catch (Standard_Failure) {
2785 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2786 SetErrorCode(aFail->GetMessageString());
2791 TopoDS_Shape aShapeShape = aShape->GetValue();
2792 TopTools_IndexedMapOfShape anEdgesIndices;
2793 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2794 // Common edges on external cylinders
2795 Handle(GEOM_Object) box_e;
2797 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2800 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2802 box_e->GetLastFunction()->SetDescription("");
2803 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2804 box_e->GetLastFunction()->SetDescription("");
2806 Handle(TColStd_HSequenceOfInteger) edges_e =
2807 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2808 box_e->GetLastFunction()->SetDescription("");
2810 if (edges_e.IsNull() || edges_e->Length() == 0) {
2811 SetErrorCode("External edges not found");
2814 int nbEdgesInFillet = 0;
2815 std::list<int> theEdges;
2816 for (int i=1; i<=edges_e->Length();i++) {
2817 int edgeID = edges_e->Value(i);
2818 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2819 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2821 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2822 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2824 theEdges.push_back(edgeID);
2828 if (theHexMesh && nbEdgesInFillet == 1)
2832 Handle(GEOM_Object) aFillet;
2834 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2836 catch (Standard_Failure) {
2837 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2838 SetErrorCode(aFail->GetMessageString());
2841 if (aFillet.IsNull()) {
2842 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2843 SetErrorCode(myLocalOperations->GetErrorCode());
2846 aFillet->GetLastFunction()->SetDescription("");
2848 TopoDS_Shape aFilletShape = aFillet->GetValue();
2850 #ifdef FILLET_FIX_TOLERANCE
2851 // VSR: 30/12/2014: temporary workaround about Fillet problem
2853 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2856 GEOMUtils::FixShapeCurves(aFilletShape);
2860 aFunction->SetValue(aFilletShape);
2863 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2864 // the following block, when enabled, leads to partitioning problems
2866 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2867 // BEGIN: Limit tolerances (debug)
2868 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2869 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2870 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2871 aCorr1->GetLastFunction()->SetDescription("");
2872 // END: Limit tolerances (debug)
2873 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2875 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2878 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2880 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2884 // Add thickness reduction elements
2885 // at the three extremities: Left, Right and Incident
2888 if (isTRL || isTRR || isTRI) {
2889 TopoDS_Shape aResShape =
2890 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2891 theRL, theWL, theLtransL, theLthinL,
2892 theRR, theWR, theLtransR, theLthinR,
2893 theRI, theWI, theLtransI, theLthinI,
2895 aFunction->SetValue(aResShape);
2898 catch (Standard_Failure) {
2899 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2900 SetErrorCode(aFail->GetMessageString());
2904 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2905 aSeq->Append(aShape);
2910 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2911 0., 0., theRF, aSeq, gp_Trsf()))
2915 // Get internal group.
2916 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2917 theRR, theLtransR, theRI, theLtransI,
2922 catch (Standard_Failure) {
2923 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2924 SetErrorCode(aFail->GetMessageString());
2928 //Make a Python command
2929 TCollection_AsciiString anEntry, aListRes("[");
2930 // Iterate over the sequence aSeq
2931 Standard_Integer aNbGroups = aSeq->Length();
2932 Standard_Integer i = 1;
2933 for (; i <= aNbGroups; i++) {
2934 Handle(Standard_Transient) anItem = aSeq->Value(i);
2935 if (anItem.IsNull()) continue;
2936 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2937 if (aGroup.IsNull()) continue;
2938 //Make a Python command
2939 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2940 aListRes += anEntry + ", ";
2942 aListRes.Trunc(aListRes.Length() - 2);
2944 GEOM::TPythonDump pd (aFunction);
2946 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2947 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2948 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2949 << theRF << ", " << theHexMesh;
2951 // thickness reduction
2953 pd << ", theRL=" << theRL << ", theWL=" << theWL
2954 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2956 pd << ", theRR=" << theRR << ", theWR=" << theWR
2957 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2959 pd << ", theRI=" << theRI << ", theWI=" << theWI
2960 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2969 //=============================================================================
2971 * MakePipeTShapeFilletWithPosition
2972 * \brief Create a T-shape object with specified caracteristics for the main and
2973 * the incident pipes (radius, width, half-length). A fillet is created
2974 * on the junction of the pipes.
2975 * The extremities of the main pipe are located on junctions points P1 and P2.
2976 * The extremity of the incident pipe is located on junction point P3.
2977 * \param theR1 Internal radius of main pipe
2978 * \param theW1 Width of main pipe
2979 * \param theL1 Half-length of main pipe
2980 * \param theR2 Internal radius of incident pipe (R2 < R1)
2981 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2982 * \param theL2 Half-length of incident pipe
2983 * \param theRF Radius of curvature of fillet
2984 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2985 * \param theP1 1st junction point of main pipe
2986 * \param theP2 2nd junction point of main pipe
2987 * \param theP3 Junction point of incident pipe
2988 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2990 //=============================================================================
2991 Handle(TColStd_HSequenceOfTransient)
2992 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2993 (double theR1, double theW1, double theL1,
2994 double theR2, double theW2, double theL2,
2995 double theRL, double theWL, double theLtransL, double theLthinL,
2996 double theRR, double theWR, double theLtransR, double theLthinR,
2997 double theRI, double theWI, double theLtransI, double theLthinI,
2998 double theRF, bool theHexMesh,
2999 Handle(GEOM_Object) theP1,
3000 Handle(GEOM_Object) theP2,
3001 Handle(GEOM_Object) theP3)
3005 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
3006 //Add a new shape function with parameters
3007 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
3008 if (aFunction.IsNull()) return NULL;
3010 //Check if the function is set correctly
3011 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
3013 // Check new position
3014 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3018 AdvancedEngine_IPipeTShape aData(aFunction);
3027 aData.SetHexMesh(theHexMesh);
3029 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3030 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3031 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3033 //Compute the resulting value
3036 if (!GetSolver()->ComputeFunction(aFunction)) {
3037 SetErrorCode("TShape driver failed");
3041 catch (Standard_Failure) {
3042 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3043 SetErrorCode(aFail->GetMessageString());
3048 TopoDS_Shape aShapeShape = aShape->GetValue();
3049 TopTools_IndexedMapOfShape anEdgesIndices;
3050 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3051 // Common edges on external cylinders
3052 Handle(GEOM_Object) box_e;
3054 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3057 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3059 box_e->GetLastFunction()->SetDescription("");
3060 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3061 box_e->GetLastFunction()->SetDescription("");
3063 Handle(TColStd_HSequenceOfInteger) edges_e =
3064 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3065 box_e->GetLastFunction()->SetDescription("");
3067 if (edges_e.IsNull() || edges_e->Length() == 0) {
3068 SetErrorCode("External edges not found");
3071 int nbEdgesInFillet = 0;
3072 std::list<int> theEdges;
3073 for (int i=1; i<=edges_e->Length();i++) {
3074 int edgeID = edges_e->Value(i);
3075 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3076 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3078 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3079 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3081 theEdges.push_back(edgeID);
3085 if (theHexMesh && nbEdgesInFillet == 1)
3089 Handle(GEOM_Object) aFillet;
3091 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3093 catch (Standard_Failure) {
3094 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3095 SetErrorCode(aFail->GetMessageString());
3098 if (aFillet.IsNull()) {
3099 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3102 aFillet->GetLastFunction()->SetDescription("");
3104 TopoDS_Shape aFilletShape = aFillet->GetValue();
3106 #ifdef FILLET_FIX_TOLERANCE
3107 // VSR: 30/12/2014: temporary workaround about Fillet problem
3109 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3112 GEOMUtils::FixShapeCurves(aFilletShape);
3116 aFunction->SetValue(aFilletShape);
3119 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3120 // the following block, when enabled, leads to partitioning problems
3122 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3123 // BEGIN: Limit tolerances (debug)
3124 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3125 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3126 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3127 aCorr1->GetLastFunction()->SetDescription("");
3128 // END: Limit tolerances (debug)
3129 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3131 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3134 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3136 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3140 // Add thickness reduction elements
3141 // at the three extremities: Left, Right and Incident
3144 if (isTRL || isTRR || isTRI) {
3145 TopoDS_Shape aResShape =
3146 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3147 theRL, theWL, theLtransL, theLthinL,
3148 theRR, theWR, theLtransR, theLthinR,
3149 theRI, theWI, theLtransI, theLthinI,
3151 aFunction->SetValue(aResShape);
3154 catch (Standard_Failure) {
3155 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3156 SetErrorCode(aFail->GetMessageString());
3161 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3162 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3163 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3164 aFunction->SetValue(aTrsf_Shape);
3166 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3167 aSeq->Append(aShape);
3172 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3173 0., 0., theRF, aSeq, aTrsf))
3177 // Get internal group.
3178 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3179 theRR, theLtransR, theRI, theLtransI,
3184 catch (Standard_Failure) {
3185 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3186 SetErrorCode(aFail->GetMessageString());
3190 //Make a Python command
3191 TCollection_AsciiString anEntry, aListRes("[");
3192 // Iterate over the sequence aSeq
3193 Standard_Integer aNbGroups = aSeq->Length();
3194 Standard_Integer i = 1;
3195 for (; i <= aNbGroups; i++) {
3196 Handle(Standard_Transient) anItem = aSeq->Value(i);
3197 if (anItem.IsNull()) continue;
3198 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3199 if (aGroup.IsNull()) continue;
3200 //Make a Python command
3201 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3202 aListRes += anEntry + ", ";
3204 aListRes.Trunc(aListRes.Length() - 2);
3206 GEOM::TPythonDump pd (aFunction);
3208 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3209 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3210 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3211 << theRF << ", " << theHexMesh << ", "
3212 << theP1 << ", " << theP2 << ", " << theP3;
3214 // thickness reduction
3216 pd << ", theRL=" << theRL << ", theWL=" << theWL
3217 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3219 pd << ", theRR=" << theRR << ", theWR=" << theWR
3220 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3222 pd << ", theRI=" << theRI << ", theWI=" << theWI
3223 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3232 //=============================================================================
3234 * This function allows to create a disk already divided into blocks. It can be
3235 * used to create divided pipes for later meshing in hexaedra.
3236 * \param theR Radius of the disk
3237 * \param theRatio Relative size of the central square diagonal against the disk diameter
3238 * \param theOrientation Plane on which the disk will be built
3239 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3240 * \return New GEOM_Object, containing the created shape.
3242 //=============================================================================
3243 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3244 int theOrientation, int thePattern)
3248 if (theOrientation != 1 &&
3249 theOrientation != 2 &&
3250 theOrientation != 3)
3252 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3256 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3258 //Add a new shape function with parameters
3259 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3260 if (aFunction.IsNull()) return NULL;
3262 //Check if the function is set correctly
3263 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3265 AdvancedEngine_IDividedDisk aData (aFunction);
3268 aData.SetRatio(theRatio);
3269 aData.SetOrientation(theOrientation);
3270 aData.SetType(thePattern);
3272 //Compute the resulting value
3275 if (!GetSolver()->ComputeFunction(aFunction)) {
3276 SetErrorCode("DividedDisk driver failed");
3280 catch (Standard_Failure) {
3281 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3282 SetErrorCode(aFail->GetMessageString());
3286 std::string aPatternStr;
3291 aPatternStr = "GEOM.SQUARE";
3294 aPatternStr = "GEOM.HEXAGON";
3298 //Make a Python command
3299 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3306 //=============================================================================
3308 * This function allows to create a disk already divided into blocks. It can be
3309 * used to create divided pipes for later meshing in hexaedra.
3310 * \param theR Radius of the disk
3311 * \param theRatio Relative size of the central square diagonal against the disk diameter
3312 * \return New GEOM_Object, containing the created shape.
3314 //=============================================================================
3315 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3316 Handle(GEOM_Object) theVec,
3324 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3326 //Add a new shape function with parameters
3327 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3328 if (aFunction.IsNull()) return NULL;
3330 //Check if the function is set correctly
3331 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3333 AdvancedEngine_IDividedDisk aData (aFunction);
3335 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3336 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3338 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3340 aData.SetCenter(aRefPnt);
3341 aData.SetVector(aRefVec);
3344 aData.SetRatio(theRatio);
3345 aData.SetType(thePattern);
3347 //Compute the resulting value
3350 if (!GetSolver()->ComputeFunction(aFunction)) {
3351 SetErrorCode("DividedDisk driver failed");
3355 catch (Standard_Failure) {
3356 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3357 SetErrorCode(aFail->GetMessageString());
3361 std::string aPatternStr;
3366 aPatternStr = "GEOM.SQUARE";
3369 aPatternStr = "GEOM.HEXAGON";
3374 //Make a Python command
3375 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3382 //=============================================================================
3384 * Builds a cylinder prepared for hexa meshes
3385 * \param theR Radius of the cylinder
3386 * \param theH Height of the cylinder
3387 * \return New GEOM_Object, containing the created shape.
3389 //=============================================================================
3390 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3397 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3399 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3400 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3402 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3404 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3405 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3406 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3408 std::string aPatternStr;
3413 aPatternStr = "GEOM.SQUARE";
3416 aPatternStr = "GEOM.HEXAGON";
3420 //Make a Python command
3421 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3427 //=============================================================================
3429 * Create a smoothing surface from a set of points
3430 * \param thelPoints list of points or compounds of points
3431 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3432 * \param theDegMax maximum degree of the resulting BSpline surface
3433 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3434 * \return New GEOM_Object, containing the created shape.
3436 //=============================================================================
3437 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3445 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3447 //Add a new shape function with parameters
3448 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3449 if (aFunction.IsNull()) return NULL;
3451 //Check if the function is set correctly
3452 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3454 AdvancedEngine_ISmoothingSurface aData (aFunction);
3456 int aLen = thelPoints.size();
3457 aData.SetLength(aLen);
3459 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3460 for (; it != thelPoints.end(); it++, ind++) {
3461 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3462 if (aRefObj.IsNull()) {
3463 SetErrorCode("NULL point or compound for bSplineFaceShape");
3466 aData.SetPntOrComp(ind, aRefObj);
3469 aData.SetNbMax(theNbMax);
3470 aData.SetDegMax(theDegMax);
3471 aData.SetDMax(theDMax);
3473 //Compute the resulting value
3476 if (!GetSolver()->ComputeFunction(aFunction)) {
3477 SetErrorCode("SmoothingSurface driver failed");
3481 catch (Standard_Failure) {
3482 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3483 SetErrorCode(aFail->GetMessageString());
3487 //Make a Python command
3488 GEOM::TPythonDump pd (aFunction);
3489 pd << aShape << " = geompy.MakeSmoothingSurface([";
3490 it = thelPoints.begin();
3492 while (it != thelPoints.end()) {
3493 pd << ", " << (*it++);
3497 << theDegMax << ", "