1 // Copyright (C) 2007-2016 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_ClsfSurf.hxx>
40 #include <GEOMAlgo_FinderShapeOn2.hxx>
41 #include <GEOMAlgo_Splitter.hxx>
43 #include <GEOMImpl_Gen.hxx>
44 #include <GEOMImpl_Types.hxx>
46 #include <GEOMImpl_IBasicOperations.hxx>
47 #include <GEOMImpl_IBooleanOperations.hxx>
48 #include <GEOMImpl_IShapesOperations.hxx>
49 #include <GEOMImpl_ITransformOperations.hxx>
50 #include <GEOMImpl_IBlocksOperations.hxx>
51 #include <GEOMImpl_I3DPrimOperations.hxx>
52 #include <GEOMImpl_ILocalOperations.hxx>
53 #include <GEOMImpl_IHealingOperations.hxx>
54 #include <GEOMImpl_IGroupOperations.hxx>
55 #include <GEOMImpl_GlueDriver.hxx>
57 #include <TDF_Tool.hxx>
58 #include <TFunction_DriverTable.hxx>
59 #include <TFunction_Driver.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_FinderShapeOn2 aFinder;
819 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
821 aClsfSurf->SetSurface(theSurface);
822 aFinder.SetShape(theShape);
823 aFinder.SetTolerance(theTolerance);
824 aFinder.SetClsf(aClsfSurf);
825 aFinder.SetShapeType(TopAbs_FACE);
826 aFinder.SetState(GEOMAlgo_ST_ON);
828 // Sets the minimal number of inner points for the faces that do not have own
829 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
831 aFinder.SetNbPntsMin(3);
832 // Sets the maximal number of inner points for edges or faces.
833 // It is useful for the cases when this number is very big (e.g =2000) to improve
834 // the performance. If this value =0, all inner points will be taken into account.
836 aFinder.SetNbPntsMax(100);
839 // Interprete results
840 Standard_Integer iErr = aFinder.ErrorStatus();
841 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
843 MESSAGE(" iErr : " << iErr);
844 TCollection_AsciiString aMsg (" iErr : ");
845 aMsg += TCollection_AsciiString(iErr);
849 Standard_Integer iWrn = aFinder.WarningStatus();
850 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
852 MESSAGE(" *** iWrn : " << iWrn);
855 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
856 TopTools_ListIteratorOfListOfShape anIter (aListRes);
858 for (; anIter.More(); anIter.Next()) {
859 theFaces.Append(anIter.Value());
865 //=============================================================================
867 * Creates and returns conical face.
869 //=============================================================================
870 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
871 (const gp_Ax2 &theAxis,
872 const double theRadius,
873 const double theRadiusThin,
874 const double theHeight,
875 const gp_Trsf &theTrsf)
877 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
878 TopoDS_Shape aResult;
881 if (aMkCone.IsDone()) {
882 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
884 for (; anExp.More(); anExp.Next()) {
885 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
887 if (aFace.IsNull() == Standard_False) {
888 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
890 if (anAdaptor.GetType() == GeomAbs_Cone) {
891 // This is a conical face. Transform and return it.
892 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
894 aResult = aTransf.Shape();
904 //=============================================================================
906 * Generate the internal group of a Pipe T-Shape
908 //=============================================================================
909 bool AdvancedEngine_IOperations::MakeInternalGroup
910 (const Handle(GEOM_Object) &theShape,
911 const double theR1, const double theLen1,
912 const double theR2, const double theLen2,
913 const double theRL, double theTransLenL,
914 const double theRR, double theTransLenR,
915 const double theRI, double theTransLenI,
916 const Handle(TColStd_HSequenceOfTransient) &theSeq,
917 const gp_Trsf &theTrsf)
921 if (theShape.IsNull()) {
925 TopoDS_Shape aShape = theShape->GetValue();
927 if (aShape.IsNull()) {
928 SetErrorCode("Shape is not defined");
933 Standard_Real aMaxTol = -RealLast();
934 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
936 for (; anExp.More(); anExp.Next()) {
937 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
939 if (aVertex.IsNull() == Standard_False) {
940 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
942 if (aTol > aMaxTol) {
948 // Construct internal surfaces.
949 Standard_Integer i = 0;
950 const Standard_Integer aMaxNbSurf = 5;
951 Handle(Geom_Surface) aSurface[aMaxNbSurf];
952 TopTools_ListOfShape aConicalFaces;
953 Standard_Real aTolConf = Precision::Confusion();
955 // 1. Construct the internal surface of main pipe.
956 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
957 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
959 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
961 // 2. Construct the internal surface of incident pipe.
962 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
964 // 3. Construct the internal surface of left reduction pipe.
965 if (theRL > aTolConf) {
966 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
968 if (theTransLenL > aTolConf) {
969 // 3.1. Construct the internal surface of left transition pipe.
970 gp_Pnt aPLeft (-theLen1, 0., 0.);
971 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
972 TopoDS_Shape aConeLeft =
973 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
975 if (aConeLeft.IsNull() == Standard_False) {
976 aConicalFaces.Append(aConeLeft);
981 // 4. Construct the internal surface of right reduction pipe.
982 if (theRR > aTolConf) {
983 // There is no need to construct another cylinder of the same radius. Skip it.
984 if (Abs(theRR - theRL) > aTolConf) {
985 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
988 if (theTransLenL > aTolConf) {
989 // 4.1. Construct the internal surface of right transition pipe.
990 gp_Pnt aPRight (theLen1, 0., 0.);
991 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
992 TopoDS_Shape aConeRight =
993 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
995 if (aConeRight.IsNull() == Standard_False) {
996 aConicalFaces.Append(aConeRight);
1001 // 5. Construct the internal surface of incident reduction pipe.
1002 if (theRI > aTolConf) {
1003 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1005 if (theTransLenI > aTolConf) {
1006 // 5.1. Construct the internal surface of incident transition pipe.
1007 gp_Pnt aPInci (0., 0., theLen2);
1008 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1009 TopoDS_Shape aConeInci =
1010 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1012 if (aConeInci.IsNull() == Standard_False) {
1013 aConicalFaces.Append(aConeInci);
1018 // Get faces that are laying on cylindrical surfaces.
1019 TopTools_ListOfShape aFaces;
1020 gp_Trsf anInvTrsf = theTrsf.Inverted();
1022 for (i = 0; i < aMaxNbSurf; i++) {
1023 if (aSurface[i].IsNull()) {
1027 aSurface[i]->Transform(theTrsf);
1029 TopTools_ListOfShape aLocalFaces;
1031 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1036 // Check if the result contains outer cylinders.
1037 // It is required for main and incident pipes.
1038 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1040 while (anIter.More()) {
1041 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1042 Standard_Boolean isInside = Standard_False;
1044 // Get a vertex from this shape
1046 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1048 if (aVtx.IsNull() == Standard_False) {
1049 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1051 aPnt.Transform(anInvTrsf);
1054 // Check if the point is inside the main pipe.
1055 isInside = (Abs(aPnt.X()) <= theLen1);
1057 // Check if the point is inside the incident pipe.
1058 isInside = (aPnt.Z() <= theLen2);
1067 // Remove this face.
1068 aLocalFaces.Remove(anIter);
1073 aFaces.Append(aLocalFaces);
1076 // Get faces that are laying on conical faces.
1077 if (aConicalFaces.IsEmpty() == Standard_False) {
1078 Handle(GEOM_Object) aCone =
1079 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1080 Handle(GEOM_Function) aFunction =
1081 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1082 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1083 Handle(GEOM_Object) aConeFromShape;
1085 for (; aFIter.More(); aFIter.Next()) {
1086 aFunction->SetValue(aFIter.Value());
1087 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1089 if (aConeFromShape.IsNull() == Standard_False) {
1090 aConeFromShape->GetLastFunction()->SetDescription("");
1091 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1092 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1094 for (; anExp.More(); anExp.Next()) {
1095 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1097 if (aConeFace.IsNull() == Standard_False) {
1098 aFaces.Append(aConeFace);
1105 // Create a group of internal faces.
1106 if (aFaces.IsEmpty() == Standard_False) {
1107 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1109 if (aGroup.IsNull() == Standard_False) {
1110 aGroup->GetLastFunction()->SetDescription("");
1111 aGroup->SetName("INTERNAL_FACES");
1113 TopTools_IndexedMapOfShape anIndices;
1114 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1116 TopExp::MapShapes(aShape, anIndices);
1118 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1120 for (; anIter.More(); anIter.Next()) {
1121 const TopoDS_Shape &aFace = anIter.Value();
1122 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1125 aSeqIDs->Append(anIndex);
1129 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1130 aGroup->GetLastFunction()->SetDescription("");
1131 theSeq->Append(aGroup);
1140 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1141 double theR1, double theW1, double theL1,
1142 double theR2, double theW2, double theL2,
1143 double theH, double theW,
1144 double theRF, bool isNormal)
1148 // Build tools for partition operation:
1149 // 1 face and 2 planes
1151 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1152 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1153 Handle(GEOM_Object) chan_racc;
1154 Handle(GEOM_Object) vi1, vi2;
1155 Handle(GEOM_Object) Te3;
1159 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1160 Vector_Z->GetLastFunction()->SetDescription("");
1163 double aSize = 2*(theL1 + theL2);
1164 double aR1Ext = theR1 + theW1;
1165 double aR2Ext = theR2 + theW2;
1166 double theVertCylinderRadius = aR2Ext + theW + theRF;
1167 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1169 // Common edges on internal cylinder
1170 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1171 box_i->GetLastFunction()->SetDescription("");
1172 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1173 box_i->GetLastFunction()->SetDescription("");
1175 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1176 TCollection_AsciiString theDesc = aFunction->GetDescription();
1177 Handle(TColStd_HSequenceOfTransient) edges_i =
1178 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1179 // Recover previous description to get rid of Propagate dump
1180 aFunction->SetDescription(theDesc);
1181 if (edges_i.IsNull() || edges_i->Length() == 0) {
1182 SetErrorCode("Internal edges not found");
1185 for (int i=1; i<=edges_i->Length();i++) {
1186 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1187 anObj->GetLastFunction()->SetDescription("");
1189 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1191 // search for vertices located on both internal pipes
1192 aFunction = theShape->GetLastFunction();
1193 theDesc = aFunction->GetDescription();
1194 Handle(TColStd_HSequenceOfTransient) vertices_i =
1195 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1196 // Recover previous description to get rid of Propagate dump
1197 aFunction->SetDescription(theDesc);
1198 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1199 SetErrorCode("Internal vertices not found");
1203 double d1min = theR2+theW2, d2min=theR2+theW2;
1204 for (int i = 1; i <= vertices_i->Length(); i++) {
1205 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1206 v->GetLastFunction()->SetDescription("");
1207 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1208 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1209 if (Abs(aP.X()) <= Precision::Confusion()) {
1210 if (Abs(aP.Y()) < d1min) {
1212 d1min = Abs(aP.Y());
1214 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1215 if (Abs(aP.X()) < d2min) {
1217 d2min = Abs(aP.X());
1221 if (vi1.IsNull() || vi2.IsNull()) {
1222 SetErrorCode("Cannot find internal intersection vertices");
1226 std::list<Handle(GEOM_Object)> theShapes;
1229 Handle(GEOM_Object) ve1, ve2;
1230 TopoDS_Vertex vertex1, vertex2;
1232 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1233 box_e->GetLastFunction()->SetDescription("");
1234 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1235 box_e->GetLastFunction()->SetDescription("");
1237 // search for vertices located on both external pipes
1238 aFunction = theShape->GetLastFunction();
1239 theDesc = aFunction->GetDescription();
1240 Handle(TColStd_HSequenceOfTransient) vertices_e =
1241 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1242 // Recover previous description to get rid of Propagate dump
1243 aFunction->SetDescription(theDesc);
1244 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1245 SetErrorCode("External vertices not found");
1249 double d1max = 0, d2max = 0;
1250 for (int i = 1; i <= vertices_e->Length(); i++) {
1251 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1252 v->GetLastFunction()->SetDescription("");
1253 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1254 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1255 if (Abs(aP.X()) <= Precision::Confusion()) {
1256 if (Abs(aP.Y()) > d1max) {
1259 d1max = Abs(aP.Y());
1261 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1262 if (Abs(aP.X()) > d2max) {
1265 d2max = Abs(aP.X());
1269 if (ve1.IsNull() || ve2.IsNull()) {
1270 SetErrorCode("Cannot find external intersection vertices");
1273 Handle(GEOM_Object) edge_e1, edge_e2;
1275 // Common edges on external cylinder
1276 aFunction = theShape->GetLastFunction();
1277 theDesc = aFunction->GetDescription();
1278 Handle(TColStd_HSequenceOfTransient) edges_e =
1279 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1280 // Recover previous description to get rid of Propagate dump
1281 aFunction->SetDescription(theDesc);
1282 if (edges_e.IsNull() || edges_e->Length() == 0) {
1283 SetErrorCode("External edges not found");
1286 ShapeAnalysis_Edge sae;
1287 for (int i=1; i<=edges_e->Length();i++) {
1288 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1289 anObj->GetLastFunction()->SetDescription("");
1290 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1291 if ( !anEdge.IsNull() &&
1292 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1293 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1294 arete_intersect_ext = anObj;
1298 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1299 if (edge_e1.IsNull()) {
1300 SetErrorCode("Edge 1 could not be built");
1304 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1305 if (edge_e2.IsNull()) {
1306 SetErrorCode("Edge 2 could not be built");
1310 edge_e1->GetLastFunction()->SetDescription("");
1311 edge_e2->GetLastFunction()->SetDescription("");
1313 std::list<Handle(GEOM_Object)> edge_e_elist;
1314 edge_e_elist.push_back(arete_intersect_int);
1315 edge_e_elist.push_back(edge_e1);
1316 edge_e_elist.push_back(arete_intersect_ext);
1317 edge_e_elist.push_back(edge_e2);
1318 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1319 if (wire_t.IsNull()) {
1320 SetErrorCode("Impossible to build wire");
1323 wire_t->GetLastFunction()->SetDescription("");
1324 face_t = myShapesOperations->MakeFace(wire_t, false);
1325 if (face_t.IsNull()) {
1326 SetErrorCode("Impossible to build face");
1329 face_t->GetLastFunction()->SetDescription("");
1331 theShapes.push_back(theShape);
1332 theShapes.push_back(vi1);
1333 theShapes.push_back(vi2);
1334 theShapes.push_back(ve1);
1335 theShapes.push_back(ve2);
1336 theShapes.push_back(edge_e1);
1337 theShapes.push_back(edge_e2);
1338 theShapes.push_back(wire_t);
1339 theShapes.push_back(face_t);
1342 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1343 int idP1, idP2, idP3, idP4;
1346 std::vector<int> LX;
1347 std::vector<int> LY;
1348 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1349 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1350 box_e->GetLastFunction()->SetDescription("");
1351 box_e = myTransformOperations->TranslateDXDYDZ
1352 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1353 box_e->GetLastFunction()->SetDescription("");
1355 aFunction = theShape->GetLastFunction();
1356 theDesc = aFunction->GetDescription();
1357 Handle(TColStd_HSequenceOfTransient) extremVertices =
1358 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1359 // Recover previous description to get rid of Propagate dump
1360 aFunction->SetDescription(theDesc);
1362 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1364 SetErrorCode("Vertices on chamfer not found");
1366 SetErrorCode("Vertices on fillet not found");
1370 theShapes.push_back(theShape);
1371 theShapes.push_back(box_e);
1372 if (extremVertices->Length() != 6) {
1373 // for (int i=1; i<=extremVertices->Length(); i++){
1374 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1376 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1377 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1378 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1379 SetErrorCode("Bad number of vertices on chamfer found");
1383 for (int i=1; i<=extremVertices->Length(); i++){
1384 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1385 aV->GetLastFunction()->SetDescription("");
1386 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1388 if (Abs(aP.X()) <= Precision::Confusion()) {
1389 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1391 if (aP.Z()-ZX > Precision::Confusion()) {
1398 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1400 if (aP.Z() - ZY > Precision::Confusion()) {
1411 if (LX.at(0) == PZX)
1414 if (LY.at(0) == PZY)
1417 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1418 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1419 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1420 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1422 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1423 if (Cote_1.IsNull()) {
1424 SetErrorCode("Impossible to build edge in thickness");
1427 Cote_1->GetLastFunction()->SetDescription("");
1429 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1430 if (Cote_2.IsNull()) {
1431 SetErrorCode("Impossible to build edge in thickness");
1434 Cote_2->GetLastFunction()->SetDescription("");
1436 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1437 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1438 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1439 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1440 if (edge_chan_princ.IsNull()) {
1441 SetErrorCode("Impossible to find edge on main pipe");
1444 edge_chan_princ->GetLastFunction()->SetDescription("");
1446 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1447 if (edge_chan_inc.IsNull()) {
1448 SetErrorCode("Impossible to find edge on incident pipe");
1451 edge_chan_inc->GetLastFunction()->SetDescription("");
1453 std::list<Handle(GEOM_Object)> edgeList1;
1454 edgeList1.push_back(edge_chan_princ);
1455 edgeList1.push_back(Cote_1);
1456 edgeList1.push_back(arete_intersect_int);
1457 edgeList1.push_back(Cote_2);
1459 // std::cerr << "Creating wire 1" << std::endl;
1460 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1461 if (wire_t.IsNull()) {
1462 SetErrorCode("Impossible to build wire");
1465 wire_t->GetLastFunction()->SetDescription("");
1467 // std::cerr << "Creating face 1" << std::endl;
1468 face_t = myShapesOperations->MakeFace(wire_t, false);
1469 if (face_t.IsNull()) {
1470 SetErrorCode("Impossible to build face");
1473 face_t->GetLastFunction()->SetDescription("");
1474 theShapes.push_back(face_t);
1476 // Create a prism from edge_chan_inc
1477 Handle(GEOM_Object) aPrismDir = myBasicOperations->MakeVectorDXDYDZ(1., 1., 0.);
1479 if (aPrismDir.IsNull()) {
1480 SetErrorCode("Impossible to build Prism direction");
1483 aPrismDir->GetLastFunction()->SetDescription("");
1484 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, aPrismDir, theR2 + theW2);
1486 if (face_t2.IsNull()) {
1487 SetErrorCode("Impossible to build face");
1490 face_t2->GetLastFunction()->SetDescription("");
1491 theShapes.push_back(face_t2);
1495 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1496 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1497 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1498 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1499 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1500 aP0->GetLastFunction()->SetDescription("");
1501 aVZ->GetLastFunction()->SetDescription("");
1502 aVXZ->GetLastFunction()->SetDescription("");
1503 aPlnOZ->GetLastFunction()->SetDescription("");
1504 aPlnOXZ->GetLastFunction()->SetDescription("");
1505 theShapes.push_back(aPlnOZ);
1506 theShapes.push_back(aPlnOXZ);
1509 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1510 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1511 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1512 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1513 Handle(TColStd_HArray1OfInteger) theMaterials;
1515 partitionShapes->Append(theShape);
1516 theTools->Append(aPlnOZ);
1517 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1518 theTools->Append(aPlnOXZ);
1519 theTools->Append(face_t);
1521 theTools->Append(face_t2);
1523 Te3 = myBooleanOperations->MakePartition
1524 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1525 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1527 SetErrorCode("Impossible to build partition of TShape");
1530 Te3->GetLastFunction()->SetDescription("");
1532 // Last verification: result should be a block
1533 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1534 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1535 SetErrorCode("TShape is not a compound of block");
1539 // // BEGIN Compound of created shapes - Only for debug purpose
1540 // theShapes.clear();
1541 // theShapes.push_back(theShape);
1542 // theShapes.push_back(aPlnOZ);
1543 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1544 // theShapes.push_back(aPlnOXZ);
1545 // theShapes.push_back(face_t);
1547 // theShapes.push_back(face_t2);
1549 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1550 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1551 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1552 // // END Compound of created shapes - Only for debug purpose
1554 TopoDS_Shape aShape = Te3->GetValue();
1555 theShape->GetLastFunction()->SetValue(aShape);
1557 catch (Standard_Failure) {
1558 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1559 SetErrorCode(aFail->GetMessageString());
1567 // Mirror and glue faces
1568 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1569 double theR1, double theW1, double theL1,
1570 double theR2, double theW2, double theL2)
1575 double aSize = 2*(theL1 + theL2);
1576 double aR1Ext = theR1 + theW1;
1579 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1580 aP0->GetLastFunction()->SetDescription("");
1581 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1582 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1583 aVX->GetLastFunction()->SetDescription("");
1584 aVY->GetLastFunction()->SetDescription("");
1585 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1586 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1587 aPlane_OX->GetLastFunction()->SetDescription("");
1588 aPlane_OY->GetLastFunction()->SetDescription("");
1590 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1592 SetErrorCode("Impossible to build mirror of quarter TShape");
1596 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1598 SetErrorCode("Impossible to build mirror of half TShape");
1602 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1604 SetErrorCode("Impossible to build mirror of half TShape");
1608 std::list<Handle(GEOM_Object)> aShapesList;
1609 aShapesList.push_back(theShape);
1610 aShapesList.push_back(Te4);
1611 aShapesList.push_back(Te5);
1612 aShapesList.push_back(Te6);
1613 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1615 SetErrorCode("Impossible to build compound");
1619 // Copy source shape
1620 TopoDS_Shape aShapeCopy;
1621 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1622 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1624 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1625 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1627 SetErrorCode("Impossible to glue faces of TShape");
1631 TopoDS_Shape aShape = Te8->GetValue();
1632 BRepCheck_Analyzer anAna (aShape, Standard_True);
1634 if (!anAna.IsValid()) {
1635 // Try to do gluing with the tolerance equal to maximal
1636 // tolerance of vertices of the source shape.
1637 Standard_Real aTolMax = -RealLast();
1639 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1640 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1641 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1643 if (aTol > aTolMax) {
1649 Te7->GetLastFunction()->SetValue(aShapeCopy);
1650 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1653 SetErrorCode("Impossible to glue faces of TShape");
1657 aShape = Te8->GetValue();
1661 theShape->GetLastFunction()->SetValue(aShape);
1663 Te4->GetLastFunction()->SetDescription("");
1664 Te5->GetLastFunction()->SetDescription("");
1665 Te6->GetLastFunction()->SetDescription("");
1666 Te7->GetLastFunction()->SetDescription("");
1667 Te8->GetLastFunction()->SetDescription("");
1673 //=======================================================================
1674 //function : MakePipeTShapeThicknessReduction
1675 //purpose : Static method. Add thiskness reduction elements at the three
1676 // open ends of the T-Shape.
1677 //=======================================================================
1678 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1679 (TopoDS_Shape theShape,
1680 double r1, double w1, double l1,
1681 double r2, double w2, double l2,
1682 double rL, double wL, double ltransL, double lthinL,
1683 double rR, double wR, double ltransR, double lthinR,
1684 double rI, double wI, double ltransI, double lthinI,
1685 bool fuseReductions)
1687 // Add thickness reduction elements
1688 // at the three extremities: Left, Right and Incident
1690 // ---------------------.
1692 // ---------------------. \
1693 // ^ \ '-----------------.
1695 // | '-----------------'
1697 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1700 TopoDS_Shape aResult = theShape;
1701 double aTol = Precision::Confusion();
1703 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1705 // Left reduction (rL, wL, ltransL, lthinL)
1706 if (rL > aTol && wL > aTol && ltransL > aTol) {
1707 gp_Pnt aPLeft (-l1, 0, 0);
1708 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1709 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1710 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1712 if (fuseReductions) {
1713 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1714 if (!fuseL.IsDone())
1715 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1716 aResult = fuseL.Shape();
1723 B.Add(C, aReductionLeft);
1729 if (rR > aTol && wR > aTol && ltransR > aTol) {
1730 gp_Pnt aPRight (l1, 0, 0);
1731 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1732 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1733 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1735 if (fuseReductions) {
1736 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1737 if (!fuseR.IsDone())
1738 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1739 aResult = fuseR.Shape();
1746 B.Add(C, aReductionRight);
1751 // Incident reduction
1752 if (rI > aTol && wI > aTol && ltransI > aTol) {
1753 gp_Pnt aPInci (0, 0, l2);
1754 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1755 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1756 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1758 if (fuseReductions) {
1759 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1760 if (!fuseInci.IsDone())
1761 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1762 aResult = fuseInci.Shape();
1769 B.Add(C, aReductionInci);
1774 // Get rid of extra compounds
1775 TopTools_ListOfShape listShapeRes;
1776 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1777 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1779 if (!fuseReductions && listShapeRes.Extent() > 1) {
1780 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1785 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1786 for (; itSub.More(); itSub.Next())
1787 B.Add(C, itSub.Value());
1790 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1796 //=======================================================================
1797 //function : MakeThicknessReduction
1798 //purpose : Static method. Create one thickness reduction element.
1799 //=======================================================================
1800 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1801 const double R, const double W,
1802 const double Rthin, const double Wthin,
1803 const double Ltrans, const double Lthin,
1806 double aTol = Precision::Confusion();
1807 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1808 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1810 bool isThinPart = (Lthin > aTol);
1815 // ^ \ '-----------------.
1817 // | '-----------------'
1819 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1822 double RExt = R + W;
1823 double RthinExt = Rthin + Wthin;
1825 gp_Dir aNormal = theAxes.Direction();
1826 gp_Dir anXDir = theAxes.XDirection();
1827 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1828 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1830 // Build the transition part
1831 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1832 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1835 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1836 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1837 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1839 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1840 TopoDS_Shape aReduction = cut1.Shape();
1842 // Build the thin part, if required
1843 TopoDS_Shape aThinPart;
1845 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1846 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1849 if (!CExt.IsDone() || !CInt.IsDone())
1850 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1851 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1853 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1854 aThinPart = cut2.Shape();
1860 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1861 if (!fuse1.IsDone())
1862 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1863 aReduction = fuse1.Shape();
1867 // Partition the reduction on blocks
1868 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1869 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1870 gp_Pln aPln1 (anAxesPln1);
1871 gp_Pln aPln2 (anAxesPln2);
1872 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1873 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1874 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1876 GEOMAlgo_Splitter PS;
1877 PS.AddArgument(aReduction);
1879 PS.AddArgument(aThinPart);
1882 PS.SetLimit(TopAbs_SOLID);
1885 aReduction = PS.Shape();
1891 //=============================================================================
1894 * \brief Create a T-shape object with specified caracteristics for the main and
1895 * the incident pipes (radius, width, half-length).
1896 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1897 * \param theR1 Internal radius of main pipe
1898 * \param theW1 Width of main pipe
1899 * \param theL1 Half-length of main pipe
1900 * \param theR2 Internal radius of incident pipe (R2 < R1)
1901 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1902 * \param theL2 Half-length of incident pipe
1903 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1904 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1906 //=============================================================================
1907 Handle(TColStd_HSequenceOfTransient)
1908 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1909 double theR2, double theW2, double theL2,
1910 double theRL, double theWL, double theLtransL, double theLthinL,
1911 double theRR, double theWR, double theLtransR, double theLthinR,
1912 double theRI, double theWI, double theLtransI, double theLthinI,
1915 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1918 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1920 //Add a new shape function with parameters
1921 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1922 if (aFunction.IsNull()) return NULL;
1924 //Check if the function is set correctly
1925 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1927 AdvancedEngine_IPipeTShape aData (aFunction);
1935 aData.SetHexMesh(theHexMesh);
1937 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1938 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1939 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1941 //Compute the resulting value
1944 if (!GetSolver()->ComputeFunction(aFunction)) {
1945 SetErrorCode("TShape driver failed");
1950 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1952 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1956 if (isTRL || isTRR || isTRI) {
1957 // Add thickness reduction elements
1958 // at the three extremities: Left, Right and Incident
1959 TopoDS_Shape aResShape =
1960 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1961 theRL, theWL, theLtransL, theLthinL,
1962 theRR, theWR, theLtransR, theLthinR,
1963 theRI, theWI, theLtransI, theLthinI,
1965 aFunction->SetValue(aResShape);
1968 catch (Standard_Failure) {
1969 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1970 SetErrorCode(aFail->GetMessageString());
1974 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1975 aSeq->Append(aShape);
1980 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1981 0., 0., 0., aSeq, gp_Trsf()))
1985 // Get internal group.
1986 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
1987 theRR, theLtransR, theRI, theLtransI,
1992 catch (Standard_Failure) {
1993 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1994 SetErrorCode(aFail->GetMessageString());
1998 //Make a Python command
1999 TCollection_AsciiString anEntry, aListRes("[");
2000 // Iterate over the sequence aSeq
2001 Standard_Integer aNbGroups = aSeq->Length();
2002 Standard_Integer i = 1;
2003 for (; i <= aNbGroups; i++) {
2004 Handle(Standard_Transient) anItem = aSeq->Value(i);
2005 if (anItem.IsNull()) continue;
2006 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2007 if (aGroup.IsNull()) continue;
2008 //Make a Python command
2009 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2010 aListRes += anEntry + ", ";
2012 aListRes.Trunc(aListRes.Length() - 2);
2014 GEOM::TPythonDump pd (aFunction);
2016 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2017 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2018 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2021 // thickness reduction
2023 pd << ", theRL=" << theRL << ", theWL=" << theWL
2024 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2026 pd << ", theRR=" << theRR << ", theWR=" << theWR
2027 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2029 pd << ", theRI=" << theRI << ", theWI=" << theWI
2030 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2039 //=============================================================================
2041 * MakePipeTShapeWithPosition
2042 * Create a T-shape object with specified caracteristics for the main and
2043 * the incident pipes (radius, width, half-length).
2044 * The extremities of the main pipe are located on junctions points P1 and P2.
2045 * The extremity of the incident pipe is located on junction point P3.
2046 * \param theR1 Internal radius of main pipe
2047 * \param theW1 Width of main pipe
2048 * \param theL1 Half-length of main pipe
2049 * \param theR2 Internal radius of incident pipe (R2 < R1)
2050 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2051 * \param theL2 Half-length of incident pipe
2052 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2053 * \param theP1 1st junction point of main pipe
2054 * \param theP2 2nd junction point of main pipe
2055 * \param theP3 Junction point of incident pipe
2056 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2058 //=============================================================================
2059 Handle(TColStd_HSequenceOfTransient)
2060 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2061 (double theR1, double theW1, double theL1,
2062 double theR2, double theW2, double theL2,
2063 double theRL, double theWL, double theLtransL, double theLthinL,
2064 double theRR, double theWR, double theLtransR, double theLthinR,
2065 double theRI, double theWI, double theLtransI, double theLthinI,
2067 Handle(GEOM_Object) theP1,
2068 Handle(GEOM_Object) theP2,
2069 Handle(GEOM_Object) theP3)
2073 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2077 //Add a new shape function with parameters
2078 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2079 if (aFunction.IsNull()) return NULL;
2081 //Check if the function is set correctly
2082 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2084 // Check new position
2085 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2089 AdvancedEngine_IPipeTShape aData(aFunction);
2097 aData.SetHexMesh(theHexMesh);
2099 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2100 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2101 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2103 //Compute the resulting value
2106 if (!GetSolver()->ComputeFunction(aFunction)) {
2107 SetErrorCode("TShape driver failed");
2112 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2114 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2118 if (isTRL || isTRR || isTRI) {
2119 // Add thickness reduction elements
2120 // at the three extremities: Left, Right and Incident
2121 TopoDS_Shape aResShape =
2122 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2123 theRL, theWL, theLtransL, theLthinL,
2124 theRR, theWR, theLtransR, theLthinR,
2125 theRI, theWI, theLtransI, theLthinI,
2127 aFunction->SetValue(aResShape);
2130 catch (Standard_Failure) {
2131 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2132 SetErrorCode(aFail->GetMessageString());
2136 TopoDS_Shape Te = aShape->GetValue();
2139 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2140 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2141 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2142 aFunction->SetValue(aTrsf_Shape);
2144 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2145 aSeq->Append(aShape);
2150 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2151 0., 0., 0., aSeq, aTrsf)) {
2156 // Get internal group.
2157 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2158 theRR, theLtransR, theRI, theLtransI,
2163 catch (Standard_Failure) {
2164 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2165 SetErrorCode(aFail->GetMessageString());
2169 //Make a Python command
2170 TCollection_AsciiString anEntry, aListRes("[");
2171 // Iterate over the sequence aSeq
2172 Standard_Integer aNbGroups = aSeq->Length();
2173 Standard_Integer i = 1;
2174 for (; i <= aNbGroups; i++) {
2175 Handle(Standard_Transient) anItem = aSeq->Value(i);
2176 if (anItem.IsNull()) continue;
2177 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2178 if (aGroup.IsNull()) continue;
2179 //Make a Python command
2180 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2181 aListRes += anEntry + ", ";
2183 aListRes.Trunc(aListRes.Length() - 2);
2185 GEOM::TPythonDump pd (aFunction);
2187 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2188 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2189 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2190 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2192 // thickness reduction
2194 pd << ", theRL=" << theRL << ", theWL=" << theWL
2195 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2197 pd << ", theRR=" << theRR << ", theWR=" << theWR
2198 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2200 pd << ", theRI=" << theRI << ", theWI=" << theWI
2201 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2210 //=============================================================================
2212 * MakePipeTShapeChamfer
2213 * Create a T-shape object with specified caracteristics for the main and
2214 * the incident pipes (radius, width, half-length). A chamfer is created
2215 * on the junction of the pipes.
2216 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2217 * \param theR1 Internal radius of main pipe
2218 * \param theW1 Width of main pipe
2219 * \param theL1 Half-length of main pipe
2220 * \param theR2 Internal radius of incident pipe (R2 < R1)
2221 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2222 * \param theL2 Half-length of incident pipe
2223 * \param theH Height of chamfer.
2224 * \param theW Width of chamfer.
2225 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2226 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2228 //=============================================================================
2229 Handle(TColStd_HSequenceOfTransient)
2230 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2231 (double theR1, double theW1, double theL1,
2232 double theR2, double theW2, double theL2,
2233 double theRL, double theWL, double theLtransL, double theLthinL,
2234 double theRR, double theWR, double theLtransR, double theLthinR,
2235 double theRI, double theWI, double theLtransI, double theLthinI,
2236 double theH, double theW,
2241 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2242 //Add a new shape function with parameters
2243 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2244 if (aFunction.IsNull()) return NULL;
2246 //Check if the function is set correctly
2247 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2249 AdvancedEngine_IPipeTShape aData(aFunction);
2259 aData.SetHexMesh(theHexMesh);
2261 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2262 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2263 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2265 //Compute the resulting value
2268 if (!GetSolver()->ComputeFunction(aFunction)) {
2269 SetErrorCode("TShape driver failed");
2273 catch (Standard_Failure) {
2274 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2275 SetErrorCode(aFail->GetMessageString());
2280 TopoDS_Shape aShapeShape = aShape->GetValue();
2281 TopTools_IndexedMapOfShape anEdgesIndices;
2282 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2283 // Common edges on external cylinders
2284 Handle(GEOM_Object) box_e;
2286 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2289 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2291 box_e->GetLastFunction()->SetDescription("");
2292 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2293 box_e->GetLastFunction()->SetDescription("");
2295 Handle(TColStd_HSequenceOfInteger) edges_e =
2296 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2297 box_e->GetLastFunction()->SetDescription("");
2299 if (edges_e.IsNull() || edges_e->Length() == 0) {
2300 SetErrorCode("External edges not found");
2303 int nbEdgesInChamfer = 0;
2304 std::list<int> theEdges;
2305 for (int i=1; i<=edges_e->Length();i++) {
2306 int edgeID = edges_e->Value(i);
2307 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2308 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2312 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2313 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2314 nbEdgesInChamfer ++;
2315 theEdges.push_back(edgeID);
2319 if (theHexMesh && nbEdgesInChamfer == 1)
2322 Handle(GEOM_Object) aChamfer;
2324 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2326 catch (Standard_Failure) {
2327 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2328 SetErrorCode(aFail->GetMessageString());
2331 if (aChamfer.IsNull()) {
2332 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2335 aChamfer->GetLastFunction()->SetDescription("");
2337 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2338 aFunction->SetValue(aChamferShape);
2342 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2344 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2348 // Add thickness reduction elements
2349 // at the three extremities: Left, Right and Incident
2352 if (isTRL || isTRR || isTRI) {
2353 TopoDS_Shape aResShape =
2354 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2355 theRL, theWL, theLtransL, theLthinL,
2356 theRR, theWR, theLtransR, theLthinR,
2357 theRI, theWI, theLtransI, theLthinI,
2359 aFunction->SetValue(aResShape);
2362 catch (Standard_Failure) {
2363 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2364 SetErrorCode(aFail->GetMessageString());
2368 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2369 aSeq->Append(aShape);
2374 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2375 theH, theW, 0., aSeq, gp_Trsf()))
2379 // Get internal group.
2380 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2381 theRR, theLtransR, theRI, theLtransI,
2386 catch (Standard_Failure) {
2387 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2388 SetErrorCode(aFail->GetMessageString());
2392 //Make a Python command
2393 TCollection_AsciiString anEntry, aListRes("[");
2394 // Iterate over the sequence aSeq
2395 Standard_Integer aNbGroups = aSeq->Length();
2396 Standard_Integer i = 1;
2397 for (; i <= aNbGroups; i++) {
2398 Handle(Standard_Transient) anItem = aSeq->Value(i);
2399 if (anItem.IsNull()) continue;
2400 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2401 if (aGroup.IsNull()) continue;
2402 //Make a Python command
2403 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2404 aListRes += anEntry + ", ";
2406 aListRes.Trunc(aListRes.Length() - 2);
2408 GEOM::TPythonDump pd (aFunction);
2410 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2411 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2412 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2413 << theH << ", " << theW << ", " << theHexMesh;
2415 // thickness reduction
2417 pd << ", theRL=" << theRL << ", theWL=" << theWL
2418 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2420 pd << ", theRR=" << theRR << ", theWR=" << theWR
2421 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2423 pd << ", theRI=" << theRI << ", theWI=" << theWI
2424 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2433 //=============================================================================
2435 * MakePipeTShapeChamferWithPosition
2436 * Create a T-shape object with specified caracteristics for the main and
2437 * the incident pipes (radius, width, half-length). A chamfer is created
2438 * on the junction of the pipes.
2439 * The extremities of the main pipe are located on junctions points P1 and P2.
2440 * The extremity of the incident pipe is located on junction point P3.
2441 * \param theR1 Internal radius of main pipe
2442 * \param theW1 Width of main pipe
2443 * \param theL1 Half-length of main pipe
2444 * \param theR2 Internal radius of incident pipe (R2 < R1)
2445 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2446 * \param theL2 Half-length of incident pipe
2447 * \param theH Height of chamfer.
2448 * \param theW Width of chamfer.
2449 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2450 * \param theP1 1st junction point of main pipe
2451 * \param theP2 2nd junction point of main pipe
2452 * \param theP3 Junction point of incident pipe
2453 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2455 //=============================================================================
2456 Handle(TColStd_HSequenceOfTransient)
2457 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2458 (double theR1, double theW1, double theL1,
2459 double theR2, double theW2, double theL2,
2460 double theRL, double theWL, double theLtransL, double theLthinL,
2461 double theRR, double theWR, double theLtransR, double theLthinR,
2462 double theRI, double theWI, double theLtransI, double theLthinI,
2463 double theH, double theW,
2465 Handle(GEOM_Object) theP1,
2466 Handle(GEOM_Object) theP2,
2467 Handle(GEOM_Object) theP3)
2471 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2472 //Add a new shape function with parameters
2473 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2474 if (aFunction.IsNull()) return NULL;
2476 //Check if the function is set correctly
2477 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2479 // Check new position
2480 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2484 AdvancedEngine_IPipeTShape aData(aFunction);
2494 aData.SetHexMesh(theHexMesh);
2496 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2497 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2498 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2500 //Compute the resulting value
2503 if (!GetSolver()->ComputeFunction(aFunction)) {
2504 SetErrorCode("TShape driver failed");
2508 catch (Standard_Failure) {
2509 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2510 SetErrorCode(aFail->GetMessageString());
2515 TopoDS_Shape aShapeShape = aShape->GetValue();
2516 TopTools_IndexedMapOfShape anEdgesIndices;
2517 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2518 // Common edges on external cylinders
2519 Handle(GEOM_Object) box_e;
2521 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2524 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2526 box_e->GetLastFunction()->SetDescription("");
2527 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2528 box_e->GetLastFunction()->SetDescription("");
2530 Handle(TColStd_HSequenceOfInteger) edges_e =
2531 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2532 box_e->GetLastFunction()->SetDescription("");
2534 if (edges_e.IsNull() || edges_e->Length() == 0) {
2535 SetErrorCode("External edges not found");
2538 int nbEdgesInChamfer = 0;
2539 std::list<int> theEdges;
2540 for (int i=1; i<=edges_e->Length();i++) {
2541 int edgeID = edges_e->Value(i);
2542 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2543 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2545 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2546 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2547 nbEdgesInChamfer ++;
2548 theEdges.push_back(edgeID);
2552 if (theHexMesh && nbEdgesInChamfer == 1)
2555 Handle(GEOM_Object) aChamfer;
2557 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2559 catch (Standard_Failure) {
2560 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2561 SetErrorCode(aFail->GetMessageString());
2564 if (aChamfer.IsNull()) {
2565 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2568 aChamfer->GetLastFunction()->SetDescription("");
2570 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2571 aFunction->SetValue(aChamferShape);
2575 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2577 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2581 // Add thickness reduction elements
2582 // at the three extremities: Left, Right and Incident
2585 if (isTRL || isTRR || isTRI) {
2586 TopoDS_Shape aResShape =
2587 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2588 theRL, theWL, theLtransL, theLthinL,
2589 theRR, theWR, theLtransR, theLthinR,
2590 theRI, theWI, theLtransI, theLthinI,
2592 aFunction->SetValue(aResShape);
2595 catch (Standard_Failure) {
2596 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2597 SetErrorCode(aFail->GetMessageString());
2602 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2603 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2604 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2605 aFunction->SetValue(aTrsf_Shape);
2607 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2608 aSeq->Append(aShape);
2613 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2614 theH, theW, 0., aSeq, aTrsf))
2618 // Get internal group.
2619 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2620 theRR, theLtransR, theRI, theLtransI,
2625 catch (Standard_Failure) {
2626 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2627 SetErrorCode(aFail->GetMessageString());
2631 //Make a Python command
2632 TCollection_AsciiString anEntry, aListRes("[");
2633 // Iterate over the sequence aSeq
2634 Standard_Integer aNbGroups = aSeq->Length();
2635 Standard_Integer i = 1;
2636 for (; i <= aNbGroups; i++) {
2637 Handle(Standard_Transient) anItem = aSeq->Value(i);
2638 if (anItem.IsNull()) continue;
2639 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2640 if (aGroup.IsNull()) continue;
2641 //Make a Python command
2642 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2643 aListRes += anEntry + ", ";
2645 aListRes.Trunc(aListRes.Length() - 2);
2647 GEOM::TPythonDump pd (aFunction);
2649 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2650 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2651 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2652 << theH << ", " << theW << ", " << theHexMesh << ", "
2653 << theP1 << ", " << theP2 << ", " << theP3;
2655 // thickness reduction
2657 pd << ", theRL=" << theRL << ", theWL=" << theWL
2658 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2660 pd << ", theRR=" << theRR << ", theWR=" << theWR
2661 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2663 pd << ", theRI=" << theRI << ", theWI=" << theWI
2664 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2673 //=============================================================================
2675 * MakePipeTShapeFillet
2676 * Create a T-shape object with specified caracteristics for the main and
2677 * the incident pipes (radius, width, half-length). A fillet is created
2678 * on the junction of the pipes.
2679 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2680 * \param theR1 Internal radius of main pipe
2681 * \param theW1 Width of main pipe
2682 * \param theL1 Half-length of main pipe
2683 * \param theR2 Internal radius of incident pipe (R2 < R1)
2684 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2685 * \param theL2 Half-length of incident pipe
2686 * \param theRF Radius of curvature of fillet.
2687 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2688 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2690 //=============================================================================
2691 Handle(TColStd_HSequenceOfTransient)
2692 AdvancedEngine_IOperations::MakePipeTShapeFillet
2693 (double theR1, double theW1, double theL1,
2694 double theR2, double theW2, double theL2,
2695 double theRL, double theWL, double theLtransL, double theLthinL,
2696 double theRR, double theWR, double theLtransR, double theLthinR,
2697 double theRI, double theWI, double theLtransI, double theLthinI,
2698 double theRF, bool theHexMesh)
2702 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2703 //Add a new shape function with parameters
2704 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2705 if (aFunction.IsNull()) return NULL;
2707 //Check if the function is set correctly
2708 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2710 AdvancedEngine_IPipeTShape aData(aFunction);
2719 aData.SetHexMesh(theHexMesh);
2721 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2722 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2723 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2725 //Compute the resulting value
2728 if (!GetSolver()->ComputeFunction(aFunction)) {
2729 SetErrorCode("TShape driver failed");
2733 catch (Standard_Failure) {
2734 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2735 SetErrorCode(aFail->GetMessageString());
2740 TopoDS_Shape aShapeShape = aShape->GetValue();
2741 TopTools_IndexedMapOfShape anEdgesIndices;
2742 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2743 // Common edges on external cylinders
2744 Handle(GEOM_Object) box_e;
2746 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2749 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2751 box_e->GetLastFunction()->SetDescription("");
2752 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2753 box_e->GetLastFunction()->SetDescription("");
2755 Handle(TColStd_HSequenceOfInteger) edges_e =
2756 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2757 box_e->GetLastFunction()->SetDescription("");
2759 if (edges_e.IsNull() || edges_e->Length() == 0) {
2760 SetErrorCode("External edges not found");
2763 int nbEdgesInFillet = 0;
2764 std::list<int> theEdges;
2765 for (int i=1; i<=edges_e->Length();i++) {
2766 int edgeID = edges_e->Value(i);
2767 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2768 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2770 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2771 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2773 theEdges.push_back(edgeID);
2777 if (theHexMesh && nbEdgesInFillet == 1)
2781 Handle(GEOM_Object) aFillet;
2783 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2785 catch (Standard_Failure) {
2786 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2787 SetErrorCode(aFail->GetMessageString());
2790 if (aFillet.IsNull()) {
2791 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2792 SetErrorCode(myLocalOperations->GetErrorCode());
2795 aFillet->GetLastFunction()->SetDescription("");
2797 TopoDS_Shape aFilletShape = aFillet->GetValue();
2799 #ifdef FILLET_FIX_TOLERANCE
2800 // VSR: 30/12/2014: temporary workaround about Fillet problem
2802 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2805 GEOMUtils::FixShapeCurves(aFilletShape);
2809 aFunction->SetValue(aFilletShape);
2812 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2813 // the following block, when enabled, leads to partitioning problems
2815 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2816 // BEGIN: Limit tolerances (debug)
2817 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2818 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2819 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2820 aCorr1->GetLastFunction()->SetDescription("");
2821 // END: Limit tolerances (debug)
2822 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2824 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2827 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2829 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2833 // Add thickness reduction elements
2834 // at the three extremities: Left, Right and Incident
2837 if (isTRL || isTRR || isTRI) {
2838 TopoDS_Shape aResShape =
2839 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2840 theRL, theWL, theLtransL, theLthinL,
2841 theRR, theWR, theLtransR, theLthinR,
2842 theRI, theWI, theLtransI, theLthinI,
2844 aFunction->SetValue(aResShape);
2847 catch (Standard_Failure) {
2848 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2849 SetErrorCode(aFail->GetMessageString());
2853 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2854 aSeq->Append(aShape);
2859 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2860 0., 0., theRF, aSeq, gp_Trsf()))
2864 // Get internal group.
2865 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2866 theRR, theLtransR, theRI, theLtransI,
2871 catch (Standard_Failure) {
2872 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2873 SetErrorCode(aFail->GetMessageString());
2877 //Make a Python command
2878 TCollection_AsciiString anEntry, aListRes("[");
2879 // Iterate over the sequence aSeq
2880 Standard_Integer aNbGroups = aSeq->Length();
2881 Standard_Integer i = 1;
2882 for (; i <= aNbGroups; i++) {
2883 Handle(Standard_Transient) anItem = aSeq->Value(i);
2884 if (anItem.IsNull()) continue;
2885 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2886 if (aGroup.IsNull()) continue;
2887 //Make a Python command
2888 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2889 aListRes += anEntry + ", ";
2891 aListRes.Trunc(aListRes.Length() - 2);
2893 GEOM::TPythonDump pd (aFunction);
2895 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2896 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2897 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2898 << theRF << ", " << theHexMesh;
2900 // thickness reduction
2902 pd << ", theRL=" << theRL << ", theWL=" << theWL
2903 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2905 pd << ", theRR=" << theRR << ", theWR=" << theWR
2906 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2908 pd << ", theRI=" << theRI << ", theWI=" << theWI
2909 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2918 //=============================================================================
2920 * MakePipeTShapeFilletWithPosition
2921 * \brief Create a T-shape object with specified caracteristics for the main and
2922 * the incident pipes (radius, width, half-length). A fillet is created
2923 * on the junction of the pipes.
2924 * The extremities of the main pipe are located on junctions points P1 and P2.
2925 * The extremity of the incident pipe is located on junction point P3.
2926 * \param theR1 Internal radius of main pipe
2927 * \param theW1 Width of main pipe
2928 * \param theL1 Half-length of main pipe
2929 * \param theR2 Internal radius of incident pipe (R2 < R1)
2930 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2931 * \param theL2 Half-length of incident pipe
2932 * \param theRF Radius of curvature of fillet
2933 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2934 * \param theP1 1st junction point of main pipe
2935 * \param theP2 2nd junction point of main pipe
2936 * \param theP3 Junction point of incident pipe
2937 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2939 //=============================================================================
2940 Handle(TColStd_HSequenceOfTransient)
2941 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2942 (double theR1, double theW1, double theL1,
2943 double theR2, double theW2, double theL2,
2944 double theRL, double theWL, double theLtransL, double theLthinL,
2945 double theRR, double theWR, double theLtransR, double theLthinR,
2946 double theRI, double theWI, double theLtransI, double theLthinI,
2947 double theRF, bool theHexMesh,
2948 Handle(GEOM_Object) theP1,
2949 Handle(GEOM_Object) theP2,
2950 Handle(GEOM_Object) theP3)
2954 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2955 //Add a new shape function with parameters
2956 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2957 if (aFunction.IsNull()) return NULL;
2959 //Check if the function is set correctly
2960 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2962 // Check new position
2963 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2967 AdvancedEngine_IPipeTShape aData(aFunction);
2976 aData.SetHexMesh(theHexMesh);
2978 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2979 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2980 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2982 //Compute the resulting value
2985 if (!GetSolver()->ComputeFunction(aFunction)) {
2986 SetErrorCode("TShape driver failed");
2990 catch (Standard_Failure) {
2991 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2992 SetErrorCode(aFail->GetMessageString());
2997 TopoDS_Shape aShapeShape = aShape->GetValue();
2998 TopTools_IndexedMapOfShape anEdgesIndices;
2999 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3000 // Common edges on external cylinders
3001 Handle(GEOM_Object) box_e;
3003 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3006 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3008 box_e->GetLastFunction()->SetDescription("");
3009 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3010 box_e->GetLastFunction()->SetDescription("");
3012 Handle(TColStd_HSequenceOfInteger) edges_e =
3013 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3014 box_e->GetLastFunction()->SetDescription("");
3016 if (edges_e.IsNull() || edges_e->Length() == 0) {
3017 SetErrorCode("External edges not found");
3020 int nbEdgesInFillet = 0;
3021 std::list<int> theEdges;
3022 for (int i=1; i<=edges_e->Length();i++) {
3023 int edgeID = edges_e->Value(i);
3024 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3025 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3027 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3028 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3030 theEdges.push_back(edgeID);
3034 if (theHexMesh && nbEdgesInFillet == 1)
3038 Handle(GEOM_Object) aFillet;
3040 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3042 catch (Standard_Failure) {
3043 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3044 SetErrorCode(aFail->GetMessageString());
3047 if (aFillet.IsNull()) {
3048 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3051 aFillet->GetLastFunction()->SetDescription("");
3053 TopoDS_Shape aFilletShape = aFillet->GetValue();
3055 #ifdef FILLET_FIX_TOLERANCE
3056 // VSR: 30/12/2014: temporary workaround about Fillet problem
3058 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3061 GEOMUtils::FixShapeCurves(aFilletShape);
3065 aFunction->SetValue(aFilletShape);
3068 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3069 // the following block, when enabled, leads to partitioning problems
3071 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3072 // BEGIN: Limit tolerances (debug)
3073 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3074 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3075 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3076 aCorr1->GetLastFunction()->SetDescription("");
3077 // END: Limit tolerances (debug)
3078 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3080 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3083 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3085 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3089 // Add thickness reduction elements
3090 // at the three extremities: Left, Right and Incident
3093 if (isTRL || isTRR || isTRI) {
3094 TopoDS_Shape aResShape =
3095 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3096 theRL, theWL, theLtransL, theLthinL,
3097 theRR, theWR, theLtransR, theLthinR,
3098 theRI, theWI, theLtransI, theLthinI,
3100 aFunction->SetValue(aResShape);
3103 catch (Standard_Failure) {
3104 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3105 SetErrorCode(aFail->GetMessageString());
3110 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3111 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3112 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3113 aFunction->SetValue(aTrsf_Shape);
3115 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3116 aSeq->Append(aShape);
3121 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3122 0., 0., theRF, aSeq, aTrsf))
3126 // Get internal group.
3127 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3128 theRR, theLtransR, theRI, theLtransI,
3133 catch (Standard_Failure) {
3134 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3135 SetErrorCode(aFail->GetMessageString());
3139 //Make a Python command
3140 TCollection_AsciiString anEntry, aListRes("[");
3141 // Iterate over the sequence aSeq
3142 Standard_Integer aNbGroups = aSeq->Length();
3143 Standard_Integer i = 1;
3144 for (; i <= aNbGroups; i++) {
3145 Handle(Standard_Transient) anItem = aSeq->Value(i);
3146 if (anItem.IsNull()) continue;
3147 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3148 if (aGroup.IsNull()) continue;
3149 //Make a Python command
3150 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3151 aListRes += anEntry + ", ";
3153 aListRes.Trunc(aListRes.Length() - 2);
3155 GEOM::TPythonDump pd (aFunction);
3157 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3158 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3159 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3160 << theRF << ", " << theHexMesh << ", "
3161 << theP1 << ", " << theP2 << ", " << theP3;
3163 // thickness reduction
3165 pd << ", theRL=" << theRL << ", theWL=" << theWL
3166 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3168 pd << ", theRR=" << theRR << ", theWR=" << theWR
3169 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3171 pd << ", theRI=" << theRI << ", theWI=" << theWI
3172 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3181 //=============================================================================
3183 * This function allows to create a disk already divided into blocks. It can be
3184 * used to create divided pipes for later meshing in hexaedra.
3185 * \param theR Radius of the disk
3186 * \param theRatio Relative size of the central square diagonal against the disk diameter
3187 * \param theOrientation Plane on which the disk will be built
3188 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3189 * \return New GEOM_Object, containing the created shape.
3191 //=============================================================================
3192 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3193 int theOrientation, int thePattern)
3197 if (theOrientation != 1 &&
3198 theOrientation != 2 &&
3199 theOrientation != 3)
3201 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3205 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3207 //Add a new shape function with parameters
3208 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3209 if (aFunction.IsNull()) return NULL;
3211 //Check if the function is set correctly
3212 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3214 AdvancedEngine_IDividedDisk aData (aFunction);
3217 aData.SetRatio(theRatio);
3218 aData.SetOrientation(theOrientation);
3219 aData.SetType(thePattern);
3221 //Compute the resulting value
3224 if (!GetSolver()->ComputeFunction(aFunction)) {
3225 SetErrorCode("DividedDisk driver failed");
3229 catch (Standard_Failure) {
3230 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3231 SetErrorCode(aFail->GetMessageString());
3235 std::string aPatternStr;
3240 aPatternStr = "GEOM.SQUARE";
3243 aPatternStr = "GEOM.HEXAGON";
3247 //Make a Python command
3248 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3255 //=============================================================================
3257 * This function allows to create a disk already divided into blocks. It can be
3258 * used to create divided pipes for later meshing in hexaedra.
3259 * \param theR Radius of the disk
3260 * \param theRatio Relative size of the central square diagonal against the disk diameter
3261 * \return New GEOM_Object, containing the created shape.
3263 //=============================================================================
3264 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3265 Handle(GEOM_Object) theVec,
3273 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3275 //Add a new shape function with parameters
3276 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3277 if (aFunction.IsNull()) return NULL;
3279 //Check if the function is set correctly
3280 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3282 AdvancedEngine_IDividedDisk aData (aFunction);
3284 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3285 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3287 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3289 aData.SetCenter(aRefPnt);
3290 aData.SetVector(aRefVec);
3293 aData.SetRatio(theRatio);
3294 aData.SetType(thePattern);
3296 //Compute the resulting value
3299 if (!GetSolver()->ComputeFunction(aFunction)) {
3300 SetErrorCode("DividedDisk driver failed");
3304 catch (Standard_Failure) {
3305 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3306 SetErrorCode(aFail->GetMessageString());
3310 std::string aPatternStr;
3315 aPatternStr = "GEOM.SQUARE";
3318 aPatternStr = "GEOM.HEXAGON";
3323 //Make a Python command
3324 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3331 //=============================================================================
3333 * Builds a cylinder prepared for hexa meshes
3334 * \param theR Radius of the cylinder
3335 * \param theH Height of the cylinder
3336 * \return New GEOM_Object, containing the created shape.
3338 //=============================================================================
3339 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3346 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3348 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3349 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3351 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3353 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3354 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3355 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3357 std::string aPatternStr;
3362 aPatternStr = "GEOM.SQUARE";
3365 aPatternStr = "GEOM.HEXAGON";
3369 //Make a Python command
3370 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3376 //=============================================================================
3378 * Create a smoothing surface from a set of points
3379 * \param thelPoints list of points or compounds of points
3380 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3381 * \param theDegMax maximum degree of the resulting BSpline surface
3382 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3383 * \return New GEOM_Object, containing the created shape.
3385 //=============================================================================
3386 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3394 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3396 //Add a new shape function with parameters
3397 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3398 if (aFunction.IsNull()) return NULL;
3400 //Check if the function is set correctly
3401 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3403 AdvancedEngine_ISmoothingSurface aData (aFunction);
3405 int aLen = thelPoints.size();
3406 aData.SetLength(aLen);
3408 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3409 for (; it != thelPoints.end(); it++, ind++) {
3410 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3411 if (aRefObj.IsNull()) {
3412 SetErrorCode("NULL point or compound for bSplineFaceShape");
3415 aData.SetPntOrComp(ind, aRefObj);
3418 aData.SetNbMax(theNbMax);
3419 aData.SetDegMax(theDegMax);
3420 aData.SetDMax(theDMax);
3422 //Compute the resulting value
3425 if (!GetSolver()->ComputeFunction(aFunction)) {
3426 SetErrorCode("SmoothingSurface driver failed");
3430 catch (Standard_Failure) {
3431 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3432 SetErrorCode(aFail->GetMessageString());
3436 //Make a Python command
3437 GEOM::TPythonDump pd (aFunction);
3438 pd << aShape << " = geompy.MakeSmoothingSurface([";
3439 it = thelPoints.begin();
3441 while (it != thelPoints.end()) {
3442 pd << ", " << (*it++);
3446 << theDegMax << ", "