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 <utilities.h>
32 #include <Utils_ExceptHandlers.hxx>
34 #include <GEOM_Function.hxx>
35 #include <GEOM_PythonDump.hxx>
36 #include <GEOMUtils.hxx>
37 #include <GEOMAlgo_ClsfSurf.hxx>
38 #include <GEOMAlgo_FinderShapeOn2.hxx>
39 #include <GEOMAlgo_Splitter.hxx>
41 #include <GEOMImpl_Gen.hxx>
42 #include <GEOMImpl_Types.hxx>
44 #include <GEOMImpl_IBasicOperations.hxx>
45 #include <GEOMImpl_IBooleanOperations.hxx>
46 #include <GEOMImpl_IShapesOperations.hxx>
47 #include <GEOMImpl_ITransformOperations.hxx>
48 #include <GEOMImpl_IBlocksOperations.hxx>
49 #include <GEOMImpl_I3DPrimOperations.hxx>
50 #include <GEOMImpl_ILocalOperations.hxx>
51 #include <GEOMImpl_IHealingOperations.hxx>
52 #include <GEOMImpl_IGroupOperations.hxx>
53 #include <GEOMImpl_GlueDriver.hxx>
55 #include <TDF_Tool.hxx>
56 #include <TFunction_DriverTable.hxx>
57 #include <TFunction_Driver.hxx>
58 #include <TNaming_CopyShape.hxx>
61 #include <TopExp_Explorer.hxx>
63 #include <TopoDS_Vertex.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
65 #include <TopTools_ListIteratorOfListOfShape.hxx>
66 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
68 #include <BRep_Builder.hxx>
69 #include <BRep_Tool.hxx>
71 #include <BRepAdaptor_Surface.hxx>
72 #include <BRepAlgoAPI_Cut.hxx>
73 #include <BRepAlgoAPI_Fuse.hxx>
74 #include <BRepBuilderAPI_MakeFace.hxx>
75 #include <BRepBuilderAPI_MakeVertex.hxx>
76 #include <BRepBuilderAPI_Transform.hxx>
77 #include <BRepPrimAPI_MakeCone.hxx>
78 #include <BRepPrimAPI_MakeCylinder.hxx>
84 #include <GC_MakeConicalSurface.hxx>
85 #include <Geom_CylindricalSurface.hxx>
87 #include <ShapeAnalysis_Edge.hxx>
91 #include "AdvancedEngine_Types.hxx"
93 #include <Standard_Stream.hxx>
94 #include <Standard_Failure.hxx>
95 #include <StdFail_NotDone.hxx>
96 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
98 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
99 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
100 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
101 #define THICKNESS "Thickness" //"Epaisseur"
102 #define FLANGE "Flange" // "Collerette"
103 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
104 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
105 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
106 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
108 #define FIND_GROUPS_BY_POINTS 1
110 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
111 // VSR 30/12/2014: macro enabled
112 #define FILLET_FIX_TOLERANCE
114 //=============================================================================
118 //=============================================================================
119 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
120 GEOM_IOperations(theEngine, theDocID)
122 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
123 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
124 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
125 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
126 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
127 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
128 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
129 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
130 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
131 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
134 //=============================================================================
138 //=============================================================================
139 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
141 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
142 delete myBasicOperations;
143 delete myBooleanOperations;
144 delete myShapesOperations;
145 delete myTransformOperations;
146 delete myBlocksOperations;
147 delete my3DPrimOperations;
148 delete myLocalOperations;
149 delete myHealingOperations;
150 delete myGroupOperations;
153 //=============================================================================
157 //=============================================================================
158 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
159 Handle(GEOM_Object) theP1,
160 Handle(GEOM_Object) theP2,
161 Handle(GEOM_Object) theP3)
163 // Old Local Coordinates System oldLCS
165 gp_Pnt P1(-theL1, 0, 0);
166 gp_Pnt P2(theL1, 0, 0);
167 gp_Pnt P3(0, 0, theL2);
169 gp_Dir oldX(gp_Vec(P1, P2));
170 gp_Dir oldZ(gp_Vec(P0, P3));
171 gp_Ax3 oldLCS(P0, oldZ, oldX);
173 // New Local Coordinates System newLCS
174 double LocX, LocY, LocZ;
175 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
176 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
177 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
178 LocX = (newP1.X() + newP2.X()) / 2.;
179 LocY = (newP1.Y() + newP2.Y()) / 2.;
180 LocZ = (newP1.Z() + newP2.Z()) / 2.;
181 gp_Pnt newO(LocX, LocY, LocZ);
183 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
184 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
185 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
188 aTrsf.SetDisplacement(oldLCS, newLCS);
193 //=============================================================================
195 * CheckCompatiblePosition
198 //=============================================================================
199 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
200 Handle(GEOM_Object) theP1,
201 Handle(GEOM_Object) theP2,
202 Handle(GEOM_Object) theP3,
206 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
207 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
208 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
210 double d12 = P1.Distance(P2);
211 double d13 = P1.Distance(P3);
212 double d23 = P2.Distance(P3);
213 // double d2 = newO.Distance(P3);
215 if (Abs(d12) <= Precision::Confusion()) {
216 SetErrorCode("Junctions points P1 and P2 are identical");
219 if (Abs(d13) <= Precision::Confusion()) {
220 SetErrorCode("Junctions points P1 and P3 are identical");
223 if (Abs(d23) <= Precision::Confusion()) {
224 SetErrorCode("Junctions points P2 and P3 are identical");
229 double newL1 = 0.5 * d12;
230 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
232 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
234 if (fabs(newL1 - theL1) > Precision::Approximation()) {
235 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
236 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
237 // std::cerr << "theL1 = newL1" << std::endl;
241 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
247 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
249 if (fabs(newL2 - theL2) > Precision::Approximation()) {
250 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
251 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
255 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
265 //=============================================================================
267 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
269 //=============================================================================
270 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
271 double theR1, double theW1, double theL1,
272 double theR2, double theW2, double theL2,
273 double theH, double theW, double theRF,
274 Handle(TColStd_HSequenceOfTransient) theSeq,
279 if (theShape.IsNull()) return false;
281 TopoDS_Shape aShape = theShape->GetValue();
282 if (aShape.IsNull()) {
283 SetErrorCode("Shape is not defined");
287 gp_Trsf aTrsfInv = aTrsf.Inverted();
289 // int expectedGroups = 0;
290 // if (shapeType == TSHAPE_BASIC)
291 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
292 // expectedGroups = 10;
294 // expectedGroups = 11;
295 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
296 // expectedGroups = 12;
298 double aR1Ext = theR1 + theW1;
299 double aR2Ext = theR2 + theW2;
301 /////////////////////////
302 //// Groups of Faces ////
303 /////////////////////////
306 // Comment the following lines when GetInPlace bug is solved
308 // Workaround of GetInPlace bug
309 // Create a bounding box that fits the shape
310 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
311 aBox->GetLastFunction()->SetDescription("");
312 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
313 aBox->GetLastFunction()->SetDescription("");
314 // Apply transformation to box
315 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
316 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
317 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
319 // Get the shell of the box
320 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
321 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
322 aBox->GetLastFunction()->SetDescription("");
323 aShell->GetLastFunction()->SetDescription("");
324 // Get the common shapes between shell and shape
325 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
326 (theShape, aShell, 1, Standard_False); // MakeCommon
327 if (aCommonCompound.IsNull()) {
328 SetErrorCode(myBooleanOperations->GetErrorCode());
331 aCommonCompound->GetLastFunction()->SetDescription("");
332 // Explode the faces of common shapes => 3 faces
333 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
334 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
335 aCommonCompound->GetLastFunction()->SetDescription("");
336 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
338 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
339 std::list<Handle(GEOM_Object)> aFacesList;
340 for (int j = 1 ; j <= 4 ; j++) {
341 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
342 if (!aFace.IsNull()) {
343 aFace->GetLastFunction()->SetDescription("");
344 aFacesList.push_back(aFace);
347 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
348 if (!aCompoundOfFaces.IsNull()) {
349 aCompoundOfFaces->GetLastFunction()->SetDescription("");
350 aCompoundOfFacesList.push_back(aCompoundOfFaces);
354 if (aCompoundOfFacesList.size() == 3) {
355 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
356 aCompoundOfFacesList.pop_front();
357 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
359 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
360 aCompoundOfFacesList.pop_front();
365 // Uncomment the following lines when GetInPlace bug is solved
367 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
368 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
369 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
370 // aP1->GetLastFunction()->SetDescription("");
371 // aP2->GetLastFunction()->SetDescription("");
372 // aP3->GetLastFunction()->SetDescription("");
373 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
374 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
375 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
376 // aV1->GetLastFunction()->SetDescription("");
377 // aV2->GetLastFunction()->SetDescription("");
378 // aV3->GetLastFunction()->SetDescription("");
379 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
380 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
381 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
382 // aPln1->GetLastFunction()->SetDescription("");
383 // aPln2->GetLastFunction()->SetDescription("");
384 // aPln3->GetLastFunction()->SetDescription("");
386 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
387 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
388 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
389 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
390 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
391 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
392 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
393 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
394 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
398 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
399 if (junctionFaces1.IsNull())
400 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
401 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
402 if (!junctionFaces1.IsNull()) {
403 junctionFaces1->GetLastFunction()->SetDescription("");
404 junctionFaces1->SetName("JUNCTION_FACE_1");
405 theSeq->Append(junctionFaces1);
408 SetErrorCode("Junction face 1 not found");
409 // theSeq->Append(aPln1);
412 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
413 if (junctionFaces2.IsNull())
414 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
415 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
416 if (!junctionFaces2.IsNull()) {
417 junctionFaces2->GetLastFunction()->SetDescription("");
418 junctionFaces2->SetName("JUNCTION_FACE_2");
419 theSeq->Append(junctionFaces2);
422 SetErrorCode("Junction face 2 not found");
423 // theSeq->Append(aPln2);
426 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
427 if (junctionFaces3.IsNull())
428 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
429 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
430 if (!junctionFaces3.IsNull()) {
431 junctionFaces3->GetLastFunction()->SetDescription("");
432 junctionFaces3->SetName("JUNCTION_FACE_3");
433 theSeq->Append(junctionFaces3);
436 SetErrorCode("Junction face 3 not found");
437 // theSeq->Append(aPln3);
440 // Comment the following lines when GetInPlace bug is solved
445 /////////////////////////
446 //// Groups of Edges ////
447 /////////////////////////
448 // Result of propagate
450 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
452 TCollection_AsciiString theDesc = aFunction->GetDescription();
453 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
454 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
455 SetErrorCode("Propagation groups not found");
458 Standard_Integer aNbGroups = aSeqPropagate->Length();
459 // Recover previous description to get rid of Propagate dump
460 aFunction->SetDescription(theDesc);
462 #ifdef FIND_GROUPS_BY_POINTS
463 // BEGIN: new groups search
470 // g / ''..| | |..'' \
472 // .---.--'.. | | | ..'--.---.
473 // |a \ '''...........''' / |
474 // |-------\------' | '------/-------.
479 // ._________________|_________________.
485 // |-----------------|-----------------|
487 // '-----------------'-----------------'
490 // "Thickness" group (a)
491 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
492 aPntA.Transform(aTrsf);
493 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
494 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
495 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
497 // "Circular quarter of pipe" group (b)
498 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
499 aPntB.Transform(aTrsf);
500 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
501 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
502 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
504 // "Circular quarter of pipe" group (c)
505 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
506 aPntC.Transform(aTrsf);
507 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
508 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
509 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
511 // "Main pipe half length" group (d)
512 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
513 aPntD.Transform(aTrsf);
514 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
515 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
516 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
518 // "Incident pipe half length" group (e)
519 double aTol10 = Precision::Confusion() * 10.;
520 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
521 aPntE.Transform(aTrsf);
522 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
523 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
524 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
526 // "Flange" group (f)
527 double aFx = - aR2Ext - aTol10;
528 if (shapeType == TSHAPE_CHAMFER)
530 else if (shapeType == TSHAPE_FILLET)
532 gp_Pnt aPntF (aFx, 0, aR1Ext);
533 aPntF.Transform(aTrsf);
534 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
535 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
536 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
538 // "Chamfer or Fillet" group (g)
539 TopoDS_Shape anEdgeG;
540 if (shapeType == TSHAPE_CHAMFER) {
541 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
542 aPntG.Transform(aTrsf);
543 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
544 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
545 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
547 else if (shapeType == TSHAPE_FILLET) {
548 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
549 aPntG.Transform(aTrsf);
550 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
551 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
552 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
555 for (int i = 1 ; i <= aNbGroups; i++) {
556 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
560 TopoDS_Shape aGroupShape = aGroup->GetValue();
561 TopTools_IndexedMapOfShape anEdgesMap;
562 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
564 if (anEdgesMap.Contains(anEdgeA)) { // a
565 aGroup->SetName("THICKNESS");
566 theSeq->Append(aGroup);
568 else if (anEdgesMap.Contains(anEdgeB)) { // b
569 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
570 theSeq->Append(aGroup);
572 else if (anEdgesMap.Contains(anEdgeC)) { // c
573 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
574 theSeq->Append(aGroup);
576 else if (anEdgesMap.Contains(anEdgeD)) { // d
577 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
578 theSeq->Append(aGroup);
580 else if (anEdgesMap.Contains(anEdgeE)) { // e
581 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
582 theSeq->Append(aGroup);
584 else if (anEdgesMap.Contains(anEdgeF)) { // f
585 aGroup->SetName("FLANGE");
586 theSeq->Append(aGroup);
588 else if (shapeType == TSHAPE_CHAMFER) { // g
589 if (anEdgesMap.Contains(anEdgeG)) {
590 aGroup->SetName("CHAMFER");
591 theSeq->Append(aGroup);
594 else if (shapeType == TSHAPE_FILLET) { // g
595 if (anEdgesMap.Contains(anEdgeG)) {
596 aGroup->SetName("FILLET");
597 theSeq->Append(aGroup);
603 // END: new groups search
606 bool circularFoundAndAdded = false;
607 bool circularFound10 = false;
608 bool incidentPipeFound = false;
609 bool mainPipeFound = false;
610 bool mainPipeFoundAndAdded = false;
611 bool radialFound =false;
612 bool flangeFound = false;
613 bool flangeFoundAndAdded = false;
614 bool chamferOrFilletFound = false;
616 for (int i = 1 ; i <= aNbGroups; i++) {
619 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
623 TopoDS_Shape aGroupShape = aGroup->GetValue();
624 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
625 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
627 TopTools_IndexedMapOfShape anEdgesMap;
628 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
629 Standard_Integer nbEdges = anEdgesMap.Extent();
631 if (shapeType == TSHAPE_BASIC) {
632 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
634 aGroup->SetName("THICKNESS");
636 else if (nbEdges == 6) {
637 if (!circularFoundAndAdded) {
638 circularFoundAndAdded = true;
640 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
643 else if (nbEdges == 8) {
644 incidentPipeFound = true;
645 mainPipeFound = false;
649 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
651 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
652 double x=aP.X(), y=aP.Y(), z=aP.Z();
655 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
656 (Abs(y) > aR2Ext + Precision::Confusion())) {
657 incidentPipeFound = false;
660 if ( z < -Precision::Confusion()) {
661 // length of main pipe
662 mainPipeFound = true;
663 if (!mainPipeFoundAndAdded) {
664 mainPipeFoundAndAdded = true;
666 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
670 else if (Abs(x) > (theL1-Precision::Confusion())) {
671 // discretisation circulaire
673 if (!circularFoundAndAdded) {
674 circularFoundAndAdded = true;
676 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
681 if (incidentPipeFound) {
683 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
685 if (!addGroup && (!incidentPipeFound &&
689 // Flange (collerette)
692 aGroup->SetName("FLANGE");
698 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
699 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
701 aGroup->SetName("THICKNESS");
703 else if ((nbEdges == 10) || (nbEdges == 6)) {
704 if (!circularFoundAndAdded) {
706 circularFoundAndAdded = true;
707 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
709 circularFound10 = true;
712 else if (!circularFound10 && nbEdges == 10) {
713 circularFound10 = true;
715 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
718 else if (nbEdges == 8) {
719 incidentPipeFound = true;
720 mainPipeFound = true;
723 bool isNearZ0 = false;
724 bool isBelowZ0 = false;
726 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
728 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
729 double x=aP.X(), y=aP.Y(), z=aP.Z();
731 // tuy_princ_long_avant & tuy_princ_long_apres
732 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
733 // ((y <= aR1Ext + Precision::Confusion()) ||
734 // (y <= -(aR1Ext + Precision::Confusion())) ||
735 // (y <= theR1 + Precision::Confusion()) ||
736 // (y == -(theR1 + Precision::Confusion()))));
737 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
738 (fabs(y) > theR1 - Precision::Confusion() ||
739 fabs(y) < Precision::Confusion()));
742 mainPipeFound = false;
746 //if (z < Precision::Confusion() && !isMain) {
747 // flangeFound = true;
748 // if (!flangeFoundAndAdded) {
749 // flangeFoundAndAdded = true;
751 // aGroup->SetName("FLANGE");
754 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
755 if (z < - Precision::Confusion()) isBelowZ0 = true;
758 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
759 (Abs(y) > aR2Ext + Precision::Confusion())) {
760 incidentPipeFound = false;
766 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
768 if (incidentPipeFound) {
770 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
772 if (isNearZ0 && !isBelowZ0) {
774 if (!flangeFoundAndAdded) {
775 flangeFoundAndAdded = true;
777 aGroup->SetName("FLANGE");
780 if (!addGroup && (!incidentPipeFound &&
783 !chamferOrFilletFound)) {
785 chamferOrFilletFound = true;
786 if (shapeType == TSHAPE_CHAMFER)
787 aGroup->SetName("CHAMFER");
789 aGroup->SetName("FILLET");
795 // Add group to the list
797 theSeq->Append(aGroup);
805 //=============================================================================
807 * Return faces that are laying on surface.
809 //=============================================================================
810 bool AdvancedEngine_IOperations::GetFacesOnSurf
811 (const TopoDS_Shape &theShape,
812 const Handle(Geom_Surface)& theSurface,
813 const Standard_Real theTolerance,
814 TopTools_ListOfShape &theFaces)
816 GEOMAlgo_FinderShapeOn2 aFinder;
817 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
819 aClsfSurf->SetSurface(theSurface);
820 aFinder.SetShape(theShape);
821 aFinder.SetTolerance(theTolerance);
822 aFinder.SetClsf(aClsfSurf);
823 aFinder.SetShapeType(TopAbs_FACE);
824 aFinder.SetState(GEOMAlgo_ST_ON);
826 // Sets the minimal number of inner points for the faces that do not have own
827 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
829 aFinder.SetNbPntsMin(3);
830 // Sets the maximal number of inner points for edges or faces.
831 // It is useful for the cases when this number is very big (e.g =2000) to improve
832 // the performance. If this value =0, all inner points will be taken into account.
834 aFinder.SetNbPntsMax(100);
837 // Interprete results
838 Standard_Integer iErr = aFinder.ErrorStatus();
839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
841 MESSAGE(" iErr : " << iErr);
842 TCollection_AsciiString aMsg (" iErr : ");
843 aMsg += TCollection_AsciiString(iErr);
847 Standard_Integer iWrn = aFinder.WarningStatus();
848 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
850 MESSAGE(" *** iWrn : " << iWrn);
853 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
854 TopTools_ListIteratorOfListOfShape anIter (aListRes);
856 for (; anIter.More(); anIter.Next()) {
857 theFaces.Append(anIter.Value());
863 //=============================================================================
865 * Creates and returns conical face.
867 //=============================================================================
868 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
869 (const gp_Ax2 &theAxis,
870 const double theRadius,
871 const double theRadiusThin,
872 const double theHeight,
873 const gp_Trsf &theTrsf)
875 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
876 TopoDS_Shape aResult;
879 if (aMkCone.IsDone()) {
880 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
882 for (; anExp.More(); anExp.Next()) {
883 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
885 if (aFace.IsNull() == Standard_False) {
886 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
888 if (anAdaptor.GetType() == GeomAbs_Cone) {
889 // This is a conical face. Transform and return it.
890 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
892 aResult = aTransf.Shape();
902 //=============================================================================
904 * Generate the internal group of a Pipe T-Shape
906 //=============================================================================
907 bool AdvancedEngine_IOperations::MakeInternalGroup
908 (const Handle(GEOM_Object) &theShape,
909 const double theR1, const double theLen1,
910 const double theR2, const double theLen2,
911 const double theRL, double theTransLenL,
912 const double theRR, double theTransLenR,
913 const double theRI, double theTransLenI,
914 const Handle(TColStd_HSequenceOfTransient) &theSeq,
915 const gp_Trsf &theTrsf)
919 if (theShape.IsNull()) {
923 TopoDS_Shape aShape = theShape->GetValue();
925 if (aShape.IsNull()) {
926 SetErrorCode("Shape is not defined");
931 Standard_Real aMaxTol = -RealLast();
932 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
934 for (; anExp.More(); anExp.Next()) {
935 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
937 if (aVertex.IsNull() == Standard_False) {
938 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
940 if (aTol > aMaxTol) {
946 // Construct internal surfaces.
947 Standard_Integer i = 0;
948 const Standard_Integer aMaxNbSurf = 5;
949 Handle(Geom_Surface) aSurface[aMaxNbSurf];
950 TopTools_ListOfShape aConicalFaces;
951 Standard_Real aTolConf = Precision::Confusion();
953 // 1. Construct the internal surface of main pipe.
954 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
955 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
957 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
959 // 2. Construct the internal surface of incident pipe.
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
962 // 3. Construct the internal surface of left reduction pipe.
963 if (theRL > aTolConf) {
964 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
966 if (theTransLenL > aTolConf) {
967 // 3.1. Construct the internal surface of left transition pipe.
968 gp_Pnt aPLeft (-theLen1, 0., 0.);
969 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
970 TopoDS_Shape aConeLeft =
971 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
973 if (aConeLeft.IsNull() == Standard_False) {
974 aConicalFaces.Append(aConeLeft);
979 // 4. Construct the internal surface of right reduction pipe.
980 if (theRR > aTolConf) {
981 // There is no need to construct another cylinder of the same radius. Skip it.
982 if (Abs(theRR - theRL) > aTolConf) {
983 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
986 if (theTransLenL > aTolConf) {
987 // 4.1. Construct the internal surface of right transition pipe.
988 gp_Pnt aPRight (theLen1, 0., 0.);
989 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
990 TopoDS_Shape aConeRight =
991 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
993 if (aConeRight.IsNull() == Standard_False) {
994 aConicalFaces.Append(aConeRight);
999 // 5. Construct the internal surface of incident reduction pipe.
1000 if (theRI > aTolConf) {
1001 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1003 if (theTransLenI > aTolConf) {
1004 // 5.1. Construct the internal surface of incident transition pipe.
1005 gp_Pnt aPInci (0., 0., theLen2);
1006 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1007 TopoDS_Shape aConeInci =
1008 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1010 if (aConeInci.IsNull() == Standard_False) {
1011 aConicalFaces.Append(aConeInci);
1016 // Get faces that are laying on cylindrical surfaces.
1017 TopTools_ListOfShape aFaces;
1018 gp_Trsf anInvTrsf = theTrsf.Inverted();
1020 for (i = 0; i < aMaxNbSurf; i++) {
1021 if (aSurface[i].IsNull()) {
1025 aSurface[i]->Transform(theTrsf);
1027 TopTools_ListOfShape aLocalFaces;
1029 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1034 // Check if the result contains outer cylinders.
1035 // It is required for main and incident pipes.
1036 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1038 while (anIter.More()) {
1039 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1040 Standard_Boolean isInside = Standard_False;
1042 // Get a vertex from this shape
1044 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1046 if (aVtx.IsNull() == Standard_False) {
1047 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1049 aPnt.Transform(anInvTrsf);
1052 // Check if the point is inside the main pipe.
1053 isInside = (Abs(aPnt.X()) <= theLen1);
1055 // Check if the point is inside the incident pipe.
1056 isInside = (aPnt.Z() <= theLen2);
1065 // Remove this face.
1066 aLocalFaces.Remove(anIter);
1071 aFaces.Append(aLocalFaces);
1074 // Get faces that are laying on conical faces.
1075 if (aConicalFaces.IsEmpty() == Standard_False) {
1076 Handle(GEOM_Object) aCone =
1077 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1078 Handle(GEOM_Function) aFunction =
1079 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1080 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1081 Handle(GEOM_Object) aConeFromShape;
1083 for (; aFIter.More(); aFIter.Next()) {
1084 aFunction->SetValue(aFIter.Value());
1085 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1087 if (aConeFromShape.IsNull() == Standard_False) {
1088 aConeFromShape->GetLastFunction()->SetDescription("");
1089 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1090 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1092 for (; anExp.More(); anExp.Next()) {
1093 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1095 if (aConeFace.IsNull() == Standard_False) {
1096 aFaces.Append(aConeFace);
1103 // Create a group of internal faces.
1104 if (aFaces.IsEmpty() == Standard_False) {
1105 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1107 if (aGroup.IsNull() == Standard_False) {
1108 aGroup->GetLastFunction()->SetDescription("");
1109 aGroup->SetName("INTERNAL_FACES");
1111 TopTools_IndexedMapOfShape anIndices;
1112 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1114 TopExp::MapShapes(aShape, anIndices);
1116 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1118 for (; anIter.More(); anIter.Next()) {
1119 const TopoDS_Shape &aFace = anIter.Value();
1120 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1123 aSeqIDs->Append(anIndex);
1127 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1128 aGroup->GetLastFunction()->SetDescription("");
1129 theSeq->Append(aGroup);
1138 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1139 double theR1, double theW1, double theL1,
1140 double theR2, double theW2, double theL2,
1141 double theH, double theW,
1142 double theRF, bool isNormal)
1146 // Build tools for partition operation:
1147 // 1 face and 2 planes
1149 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1150 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1151 Handle(GEOM_Object) chan_racc;
1152 Handle(GEOM_Object) vi1, vi2;
1153 Handle(GEOM_Object) Te3;
1157 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1158 Vector_Z->GetLastFunction()->SetDescription("");
1161 double aSize = 2*(theL1 + theL2);
1162 double aR1Ext = theR1 + theW1;
1163 double aR2Ext = theR2 + theW2;
1164 double theVertCylinderRadius = aR2Ext + theW + theRF;
1165 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1167 // Common edges on internal cylinder
1168 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1169 box_i->GetLastFunction()->SetDescription("");
1170 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1171 box_i->GetLastFunction()->SetDescription("");
1173 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1174 TCollection_AsciiString theDesc = aFunction->GetDescription();
1175 Handle(TColStd_HSequenceOfTransient) edges_i =
1176 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1177 // Recover previous description to get rid of Propagate dump
1178 aFunction->SetDescription(theDesc);
1179 if (edges_i.IsNull() || edges_i->Length() == 0) {
1180 SetErrorCode("Internal edges not found");
1183 for (int i=1; i<=edges_i->Length();i++) {
1184 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1185 anObj->GetLastFunction()->SetDescription("");
1187 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1189 // search for vertices located on both internal pipes
1190 aFunction = theShape->GetLastFunction();
1191 theDesc = aFunction->GetDescription();
1192 Handle(TColStd_HSequenceOfTransient) vertices_i =
1193 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1194 // Recover previous description to get rid of Propagate dump
1195 aFunction->SetDescription(theDesc);
1196 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1197 SetErrorCode("Internal vertices not found");
1201 double d1min = theR2+theW2, d2min=theR2+theW2;
1202 for (int i = 1; i <= vertices_i->Length(); i++) {
1203 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1204 v->GetLastFunction()->SetDescription("");
1205 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1206 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1207 if (Abs(aP.X()) <= Precision::Confusion()) {
1208 if (Abs(aP.Y()) < d1min) {
1210 d1min = Abs(aP.Y());
1212 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1213 if (Abs(aP.X()) < d2min) {
1215 d2min = Abs(aP.X());
1219 if (vi1.IsNull() || vi2.IsNull()) {
1220 SetErrorCode("Cannot find internal intersection vertices");
1224 std::list<Handle(GEOM_Object)> theShapes;
1227 Handle(GEOM_Object) ve1, ve2;
1228 TopoDS_Vertex vertex1, vertex2;
1230 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1231 box_e->GetLastFunction()->SetDescription("");
1232 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1233 box_e->GetLastFunction()->SetDescription("");
1235 // search for vertices located on both external pipes
1236 aFunction = theShape->GetLastFunction();
1237 theDesc = aFunction->GetDescription();
1238 Handle(TColStd_HSequenceOfTransient) vertices_e =
1239 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1240 // Recover previous description to get rid of Propagate dump
1241 aFunction->SetDescription(theDesc);
1242 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1243 SetErrorCode("External vertices not found");
1247 double d1max = 0, d2max = 0;
1248 for (int i = 1; i <= vertices_e->Length(); i++) {
1249 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1250 v->GetLastFunction()->SetDescription("");
1251 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1252 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1253 if (Abs(aP.X()) <= Precision::Confusion()) {
1254 if (Abs(aP.Y()) > d1max) {
1257 d1max = Abs(aP.Y());
1259 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1260 if (Abs(aP.X()) > d2max) {
1263 d2max = Abs(aP.X());
1267 if (ve1.IsNull() || ve2.IsNull()) {
1268 SetErrorCode("Cannot find external intersection vertices");
1271 Handle(GEOM_Object) edge_e1, edge_e2;
1273 // Common edges on external cylinder
1274 aFunction = theShape->GetLastFunction();
1275 theDesc = aFunction->GetDescription();
1276 Handle(TColStd_HSequenceOfTransient) edges_e =
1277 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1278 // Recover previous description to get rid of Propagate dump
1279 aFunction->SetDescription(theDesc);
1280 if (edges_e.IsNull() || edges_e->Length() == 0) {
1281 SetErrorCode("External edges not found");
1284 ShapeAnalysis_Edge sae;
1285 for (int i=1; i<=edges_e->Length();i++) {
1286 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1287 anObj->GetLastFunction()->SetDescription("");
1288 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1289 if ( !anEdge.IsNull() &&
1290 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1291 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1292 arete_intersect_ext = anObj;
1296 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1297 if (edge_e1.IsNull()) {
1298 SetErrorCode("Edge 1 could not be built");
1302 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1303 if (edge_e2.IsNull()) {
1304 SetErrorCode("Edge 2 could not be built");
1308 edge_e1->GetLastFunction()->SetDescription("");
1309 edge_e2->GetLastFunction()->SetDescription("");
1311 std::list<Handle(GEOM_Object)> edge_e_elist;
1312 edge_e_elist.push_back(arete_intersect_int);
1313 edge_e_elist.push_back(edge_e1);
1314 edge_e_elist.push_back(arete_intersect_ext);
1315 edge_e_elist.push_back(edge_e2);
1316 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1317 if (wire_t.IsNull()) {
1318 SetErrorCode("Impossible to build wire");
1321 wire_t->GetLastFunction()->SetDescription("");
1322 face_t = myShapesOperations->MakeFace(wire_t, false);
1323 if (face_t.IsNull()) {
1324 SetErrorCode("Impossible to build face");
1327 face_t->GetLastFunction()->SetDescription("");
1329 theShapes.push_back(theShape);
1330 theShapes.push_back(vi1);
1331 theShapes.push_back(vi2);
1332 theShapes.push_back(ve1);
1333 theShapes.push_back(ve2);
1334 theShapes.push_back(edge_e1);
1335 theShapes.push_back(edge_e2);
1336 theShapes.push_back(wire_t);
1337 theShapes.push_back(face_t);
1340 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1341 int idP1, idP2, idP3, idP4;
1344 std::vector<int> LX;
1345 std::vector<int> LY;
1346 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1347 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1348 box_e->GetLastFunction()->SetDescription("");
1349 box_e = myTransformOperations->TranslateDXDYDZ
1350 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1351 box_e->GetLastFunction()->SetDescription("");
1353 aFunction = theShape->GetLastFunction();
1354 theDesc = aFunction->GetDescription();
1355 Handle(TColStd_HSequenceOfTransient) extremVertices =
1356 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1357 // Recover previous description to get rid of Propagate dump
1358 aFunction->SetDescription(theDesc);
1360 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1362 SetErrorCode("Vertices on chamfer not found");
1364 SetErrorCode("Vertices on fillet not found");
1368 theShapes.push_back(theShape);
1369 theShapes.push_back(box_e);
1370 if (extremVertices->Length() != 6) {
1371 // for (int i=1; i<=extremVertices->Length(); i++){
1372 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1374 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1375 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1376 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1377 SetErrorCode("Bad number of vertices on chamfer found");
1381 for (int i=1; i<=extremVertices->Length(); i++){
1382 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1383 aV->GetLastFunction()->SetDescription("");
1384 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1386 if (Abs(aP.X()) <= Precision::Confusion()) {
1387 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1389 if (aP.Z()-ZX > Precision::Confusion()) {
1396 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1398 if (aP.Z() - ZY > Precision::Confusion()) {
1409 if (LX.at(0) == PZX)
1412 if (LY.at(0) == PZY)
1415 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1416 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1417 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1418 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1420 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1421 if (Cote_1.IsNull()) {
1422 SetErrorCode("Impossible to build edge in thickness");
1425 Cote_1->GetLastFunction()->SetDescription("");
1427 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1428 if (Cote_2.IsNull()) {
1429 SetErrorCode("Impossible to build edge in thickness");
1432 Cote_2->GetLastFunction()->SetDescription("");
1434 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1435 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1436 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1437 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1438 if (edge_chan_princ.IsNull()) {
1439 SetErrorCode("Impossible to find edge on main pipe");
1442 edge_chan_princ->GetLastFunction()->SetDescription("");
1444 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1445 if (edge_chan_inc.IsNull()) {
1446 SetErrorCode("Impossible to find edge on incident pipe");
1449 edge_chan_inc->GetLastFunction()->SetDescription("");
1451 std::list<Handle(GEOM_Object)> edgeList1;
1452 edgeList1.push_back(edge_chan_princ);
1453 edgeList1.push_back(Cote_1);
1454 edgeList1.push_back(arete_intersect_int);
1455 edgeList1.push_back(Cote_2);
1457 // std::cerr << "Creating wire 1" << std::endl;
1458 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1459 if (wire_t.IsNull()) {
1460 SetErrorCode("Impossible to build wire");
1463 wire_t->GetLastFunction()->SetDescription("");
1465 // std::cerr << "Creating face 1" << std::endl;
1466 face_t = myShapesOperations->MakeFace(wire_t, false);
1467 if (face_t.IsNull()) {
1468 SetErrorCode("Impossible to build face");
1471 face_t->GetLastFunction()->SetDescription("");
1472 theShapes.push_back(face_t);
1474 // Create a prism from edge_chan_inc
1475 Handle(GEOM_Object) aPrismDir = myBasicOperations->MakeVectorDXDYDZ(1., 1., 0.);
1477 if (aPrismDir.IsNull()) {
1478 SetErrorCode("Impossible to build Prism direction");
1481 aPrismDir->GetLastFunction()->SetDescription("");
1482 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, aPrismDir, theR2 + theW2);
1484 if (face_t2.IsNull()) {
1485 SetErrorCode("Impossible to build face");
1488 face_t2->GetLastFunction()->SetDescription("");
1489 theShapes.push_back(face_t2);
1493 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1494 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1495 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1496 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1497 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1498 aP0->GetLastFunction()->SetDescription("");
1499 aVZ->GetLastFunction()->SetDescription("");
1500 aVXZ->GetLastFunction()->SetDescription("");
1501 aPlnOZ->GetLastFunction()->SetDescription("");
1502 aPlnOXZ->GetLastFunction()->SetDescription("");
1503 theShapes.push_back(aPlnOZ);
1504 theShapes.push_back(aPlnOXZ);
1507 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1508 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1509 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1510 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1511 Handle(TColStd_HArray1OfInteger) theMaterials;
1513 partitionShapes->Append(theShape);
1514 theTools->Append(aPlnOZ);
1515 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1516 theTools->Append(aPlnOXZ);
1517 theTools->Append(face_t);
1519 theTools->Append(face_t2);
1521 Te3 = myBooleanOperations->MakePartition
1522 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1523 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1525 SetErrorCode("Impossible to build partition of TShape");
1528 Te3->GetLastFunction()->SetDescription("");
1530 // Last verification: result should be a block
1531 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1532 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1533 SetErrorCode("TShape is not a compound of block");
1537 // // BEGIN Compound of created shapes - Only for debug purpose
1538 // theShapes.clear();
1539 // theShapes.push_back(theShape);
1540 // theShapes.push_back(aPlnOZ);
1541 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1542 // theShapes.push_back(aPlnOXZ);
1543 // theShapes.push_back(face_t);
1545 // theShapes.push_back(face_t2);
1547 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1548 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1549 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1550 // // END Compound of created shapes - Only for debug purpose
1552 TopoDS_Shape aShape = Te3->GetValue();
1553 theShape->GetLastFunction()->SetValue(aShape);
1555 catch (Standard_Failure& aFail) {
1556 SetErrorCode(aFail.GetMessageString());
1564 // Mirror and glue faces
1565 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1566 double theR1, double theW1, double theL1,
1567 double theR2, double theW2, double theL2)
1572 double aSize = 2*(theL1 + theL2);
1573 double aR1Ext = theR1 + theW1;
1576 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1577 aP0->GetLastFunction()->SetDescription("");
1578 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1579 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1580 aVX->GetLastFunction()->SetDescription("");
1581 aVY->GetLastFunction()->SetDescription("");
1582 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1583 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1584 aPlane_OX->GetLastFunction()->SetDescription("");
1585 aPlane_OY->GetLastFunction()->SetDescription("");
1587 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1589 SetErrorCode("Impossible to build mirror of quarter TShape");
1593 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1595 SetErrorCode("Impossible to build mirror of half TShape");
1599 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1601 SetErrorCode("Impossible to build mirror of half TShape");
1605 std::list<Handle(GEOM_Object)> aShapesList;
1606 aShapesList.push_back(theShape);
1607 aShapesList.push_back(Te4);
1608 aShapesList.push_back(Te5);
1609 aShapesList.push_back(Te6);
1610 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1612 SetErrorCode("Impossible to build compound");
1616 // Copy source shape
1617 TopoDS_Shape aShapeCopy;
1618 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1619 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1621 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1622 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1624 SetErrorCode("Impossible to glue faces of TShape");
1628 TopoDS_Shape aShape = Te8->GetValue();
1629 BRepCheck_Analyzer anAna (aShape, Standard_True);
1631 if (!anAna.IsValid()) {
1632 // Try to do gluing with the tolerance equal to maximal
1633 // tolerance of vertices of the source shape.
1634 Standard_Real aTolMax = -RealLast();
1636 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1637 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1638 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1640 if (aTol > aTolMax) {
1646 Te7->GetLastFunction()->SetValue(aShapeCopy);
1647 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1650 SetErrorCode("Impossible to glue faces of TShape");
1654 aShape = Te8->GetValue();
1658 theShape->GetLastFunction()->SetValue(aShape);
1660 Te4->GetLastFunction()->SetDescription("");
1661 Te5->GetLastFunction()->SetDescription("");
1662 Te6->GetLastFunction()->SetDescription("");
1663 Te7->GetLastFunction()->SetDescription("");
1664 Te8->GetLastFunction()->SetDescription("");
1670 //=======================================================================
1671 //function : MakePipeTShapeThicknessReduction
1672 //purpose : Static method. Add thiskness reduction elements at the three
1673 // open ends of the T-Shape.
1674 //=======================================================================
1675 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1676 (TopoDS_Shape theShape,
1677 double r1, double w1, double l1,
1678 double r2, double w2, double l2,
1679 double rL, double wL, double ltransL, double lthinL,
1680 double rR, double wR, double ltransR, double lthinR,
1681 double rI, double wI, double ltransI, double lthinI,
1682 bool fuseReductions)
1684 // Add thickness reduction elements
1685 // at the three extremities: Left, Right and Incident
1687 // ---------------------.
1689 // ---------------------. \
1690 // ^ \ '-----------------.
1692 // | '-----------------'
1694 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1697 TopoDS_Shape aResult = theShape;
1698 double aTol = Precision::Confusion();
1700 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1702 // Left reduction (rL, wL, ltransL, lthinL)
1703 if (rL > aTol && wL > aTol && ltransL > aTol) {
1704 gp_Pnt aPLeft (-l1, 0, 0);
1705 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1706 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1707 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1709 if (fuseReductions) {
1710 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1711 if (!fuseL.IsDone())
1712 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1713 aResult = fuseL.Shape();
1720 B.Add(C, aReductionLeft);
1726 if (rR > aTol && wR > aTol && ltransR > aTol) {
1727 gp_Pnt aPRight (l1, 0, 0);
1728 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1729 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1730 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1732 if (fuseReductions) {
1733 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1734 if (!fuseR.IsDone())
1735 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1736 aResult = fuseR.Shape();
1743 B.Add(C, aReductionRight);
1748 // Incident reduction
1749 if (rI > aTol && wI > aTol && ltransI > aTol) {
1750 gp_Pnt aPInci (0, 0, l2);
1751 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1752 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1753 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1755 if (fuseReductions) {
1756 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1757 if (!fuseInci.IsDone())
1758 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1759 aResult = fuseInci.Shape();
1766 B.Add(C, aReductionInci);
1771 // Get rid of extra compounds
1772 TopTools_ListOfShape listShapeRes;
1773 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1774 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1776 if (!fuseReductions && listShapeRes.Extent() > 1) {
1777 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1782 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1783 for (; itSub.More(); itSub.Next())
1784 B.Add(C, itSub.Value());
1787 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1793 //=======================================================================
1794 //function : MakeThicknessReduction
1795 //purpose : Static method. Create one thickness reduction element.
1796 //=======================================================================
1797 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1798 const double R, const double W,
1799 const double Rthin, const double Wthin,
1800 const double Ltrans, const double Lthin,
1803 double aTol = Precision::Confusion();
1804 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1805 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1807 bool isThinPart = (Lthin > aTol);
1812 // ^ \ '-----------------.
1814 // | '-----------------'
1816 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1819 double RExt = R + W;
1820 double RthinExt = Rthin + Wthin;
1822 gp_Dir aNormal = theAxes.Direction();
1823 gp_Dir anXDir = theAxes.XDirection();
1824 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1825 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1827 // Build the transition part
1828 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1829 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1832 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1833 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1834 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1836 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1837 TopoDS_Shape aReduction = cut1.Shape();
1839 // Build the thin part, if required
1840 TopoDS_Shape aThinPart;
1842 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1843 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1846 if (!CExt.IsDone() || !CInt.IsDone())
1847 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1848 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1850 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1851 aThinPart = cut2.Shape();
1857 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1858 if (!fuse1.IsDone())
1859 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1860 aReduction = fuse1.Shape();
1864 // Partition the reduction on blocks
1865 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1866 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1867 gp_Pln aPln1 (anAxesPln1);
1868 gp_Pln aPln2 (anAxesPln2);
1869 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1870 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1871 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1873 GEOMAlgo_Splitter PS;
1874 PS.AddArgument(aReduction);
1876 PS.AddArgument(aThinPart);
1879 PS.SetLimit(TopAbs_SOLID);
1882 aReduction = PS.Shape();
1888 //=============================================================================
1891 * \brief Create a T-shape object with specified caracteristics for the main and
1892 * the incident pipes (radius, width, half-length).
1893 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1894 * \param theR1 Internal radius of main pipe
1895 * \param theW1 Width of main pipe
1896 * \param theL1 Half-length of main pipe
1897 * \param theR2 Internal radius of incident pipe (R2 < R1)
1898 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1899 * \param theL2 Half-length of incident pipe
1900 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1901 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1903 //=============================================================================
1904 Handle(TColStd_HSequenceOfTransient)
1905 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1906 double theR2, double theW2, double theL2,
1907 double theRL, double theWL, double theLtransL, double theLthinL,
1908 double theRR, double theWR, double theLtransR, double theLthinR,
1909 double theRI, double theWI, double theLtransI, double theLthinI,
1912 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1915 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1917 //Add a new shape function with parameters
1918 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1919 if (aFunction.IsNull()) return NULL;
1921 //Check if the function is set correctly
1922 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1924 AdvancedEngine_IPipeTShape aData (aFunction);
1932 aData.SetHexMesh(theHexMesh);
1934 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1935 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1936 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1938 //Compute the resulting value
1941 if (!GetSolver()->ComputeFunction(aFunction)) {
1942 SetErrorCode("TShape driver failed");
1947 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1949 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1953 if (isTRL || isTRR || isTRI) {
1954 // Add thickness reduction elements
1955 // at the three extremities: Left, Right and Incident
1956 TopoDS_Shape aResShape =
1957 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1958 theRL, theWL, theLtransL, theLthinL,
1959 theRR, theWR, theLtransR, theLthinR,
1960 theRI, theWI, theLtransI, theLthinI,
1962 aFunction->SetValue(aResShape);
1965 catch (Standard_Failure& aFail) {
1966 SetErrorCode(aFail.GetMessageString());
1970 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1971 aSeq->Append(aShape);
1976 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1977 0., 0., 0., aSeq, gp_Trsf()))
1981 // Get internal group.
1982 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
1983 theRR, theLtransR, theRI, theLtransI,
1988 catch (Standard_Failure& aFail) {
1989 SetErrorCode(aFail.GetMessageString());
1993 //Make a Python command
1994 TCollection_AsciiString anEntry, aListRes("[");
1995 // Iterate over the sequence aSeq
1996 Standard_Integer aNbGroups = aSeq->Length();
1997 Standard_Integer i = 1;
1998 for (; i <= aNbGroups; i++) {
1999 Handle(Standard_Transient) anItem = aSeq->Value(i);
2000 if (anItem.IsNull()) continue;
2001 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2002 if (aGroup.IsNull()) continue;
2003 //Make a Python command
2004 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2005 aListRes += anEntry + ", ";
2007 aListRes.Trunc(aListRes.Length() - 2);
2009 GEOM::TPythonDump pd (aFunction);
2011 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2012 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2013 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2016 // thickness reduction
2018 pd << ", theRL=" << theRL << ", theWL=" << theWL
2019 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2021 pd << ", theRR=" << theRR << ", theWR=" << theWR
2022 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2024 pd << ", theRI=" << theRI << ", theWI=" << theWI
2025 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2034 //=============================================================================
2036 * MakePipeTShapeWithPosition
2037 * Create a T-shape object with specified caracteristics for the main and
2038 * the incident pipes (radius, width, half-length).
2039 * The extremities of the main pipe are located on junctions points P1 and P2.
2040 * The extremity of the incident pipe is located on junction point P3.
2041 * \param theR1 Internal radius of main pipe
2042 * \param theW1 Width of main pipe
2043 * \param theL1 Half-length of main pipe
2044 * \param theR2 Internal radius of incident pipe (R2 < R1)
2045 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2046 * \param theL2 Half-length of incident pipe
2047 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2048 * \param theP1 1st junction point of main pipe
2049 * \param theP2 2nd junction point of main pipe
2050 * \param theP3 Junction point of incident pipe
2051 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2053 //=============================================================================
2054 Handle(TColStd_HSequenceOfTransient)
2055 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2056 (double theR1, double theW1, double theL1,
2057 double theR2, double theW2, double theL2,
2058 double theRL, double theWL, double theLtransL, double theLthinL,
2059 double theRR, double theWR, double theLtransR, double theLthinR,
2060 double theRI, double theWI, double theLtransI, double theLthinI,
2062 Handle(GEOM_Object) theP1,
2063 Handle(GEOM_Object) theP2,
2064 Handle(GEOM_Object) theP3)
2068 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2072 //Add a new shape function with parameters
2073 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2074 if (aFunction.IsNull()) return NULL;
2076 //Check if the function is set correctly
2077 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2079 // Check new position
2080 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2084 AdvancedEngine_IPipeTShape aData(aFunction);
2092 aData.SetHexMesh(theHexMesh);
2094 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2095 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2096 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2098 //Compute the resulting value
2101 if (!GetSolver()->ComputeFunction(aFunction)) {
2102 SetErrorCode("TShape driver failed");
2107 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2109 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2113 if (isTRL || isTRR || isTRI) {
2114 // Add thickness reduction elements
2115 // at the three extremities: Left, Right and Incident
2116 TopoDS_Shape aResShape =
2117 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2118 theRL, theWL, theLtransL, theLthinL,
2119 theRR, theWR, theLtransR, theLthinR,
2120 theRI, theWI, theLtransI, theLthinI,
2122 aFunction->SetValue(aResShape);
2125 catch (Standard_Failure& aFail) {
2126 SetErrorCode(aFail.GetMessageString());
2130 TopoDS_Shape Te = aShape->GetValue();
2133 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2134 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2135 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2136 aFunction->SetValue(aTrsf_Shape);
2138 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2139 aSeq->Append(aShape);
2144 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2145 0., 0., 0., aSeq, aTrsf)) {
2150 // Get internal group.
2151 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2152 theRR, theLtransR, theRI, theLtransI,
2157 catch (Standard_Failure& aFail) {
2158 SetErrorCode(aFail.GetMessageString());
2162 //Make a Python command
2163 TCollection_AsciiString anEntry, aListRes("[");
2164 // Iterate over the sequence aSeq
2165 Standard_Integer aNbGroups = aSeq->Length();
2166 Standard_Integer i = 1;
2167 for (; i <= aNbGroups; i++) {
2168 Handle(Standard_Transient) anItem = aSeq->Value(i);
2169 if (anItem.IsNull()) continue;
2170 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2171 if (aGroup.IsNull()) continue;
2172 //Make a Python command
2173 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2174 aListRes += anEntry + ", ";
2176 aListRes.Trunc(aListRes.Length() - 2);
2178 GEOM::TPythonDump pd (aFunction);
2180 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2181 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2182 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2183 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2185 // thickness reduction
2187 pd << ", theRL=" << theRL << ", theWL=" << theWL
2188 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2190 pd << ", theRR=" << theRR << ", theWR=" << theWR
2191 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2193 pd << ", theRI=" << theRI << ", theWI=" << theWI
2194 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2203 //=============================================================================
2205 * MakePipeTShapeChamfer
2206 * Create a T-shape object with specified caracteristics for the main and
2207 * the incident pipes (radius, width, half-length). A chamfer is created
2208 * on the junction of the pipes.
2209 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2210 * \param theR1 Internal radius of main pipe
2211 * \param theW1 Width of main pipe
2212 * \param theL1 Half-length of main pipe
2213 * \param theR2 Internal radius of incident pipe (R2 < R1)
2214 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2215 * \param theL2 Half-length of incident pipe
2216 * \param theH Height of chamfer.
2217 * \param theW Width of chamfer.
2218 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2219 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2221 //=============================================================================
2222 Handle(TColStd_HSequenceOfTransient)
2223 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2224 (double theR1, double theW1, double theL1,
2225 double theR2, double theW2, double theL2,
2226 double theRL, double theWL, double theLtransL, double theLthinL,
2227 double theRR, double theWR, double theLtransR, double theLthinR,
2228 double theRI, double theWI, double theLtransI, double theLthinI,
2229 double theH, double theW,
2234 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2235 //Add a new shape function with parameters
2236 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2237 if (aFunction.IsNull()) return NULL;
2239 //Check if the function is set correctly
2240 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2242 AdvancedEngine_IPipeTShape aData(aFunction);
2252 aData.SetHexMesh(theHexMesh);
2254 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2255 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2256 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2258 //Compute the resulting value
2261 if (!GetSolver()->ComputeFunction(aFunction)) {
2262 SetErrorCode("TShape driver failed");
2266 catch (Standard_Failure& aFail) {
2267 SetErrorCode(aFail.GetMessageString());
2272 TopoDS_Shape aShapeShape = aShape->GetValue();
2273 TopTools_IndexedMapOfShape anEdgesIndices;
2274 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2275 // Common edges on external cylinders
2276 Handle(GEOM_Object) box_e;
2278 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2281 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2283 box_e->GetLastFunction()->SetDescription("");
2284 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2285 box_e->GetLastFunction()->SetDescription("");
2287 Handle(TColStd_HSequenceOfInteger) edges_e =
2288 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2289 box_e->GetLastFunction()->SetDescription("");
2291 if (edges_e.IsNull() || edges_e->Length() == 0) {
2292 SetErrorCode("External edges not found");
2295 int nbEdgesInChamfer = 0;
2296 std::list<int> theEdges;
2297 for (int i=1; i<=edges_e->Length();i++) {
2298 int edgeID = edges_e->Value(i);
2299 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2300 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2304 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2305 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2306 nbEdgesInChamfer ++;
2307 theEdges.push_back(edgeID);
2311 if (theHexMesh && nbEdgesInChamfer == 1)
2314 Handle(GEOM_Object) aChamfer;
2316 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2318 catch (Standard_Failure& aFail) {
2319 SetErrorCode(aFail.GetMessageString());
2322 if (aChamfer.IsNull()) {
2323 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2326 aChamfer->GetLastFunction()->SetDescription("");
2328 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2329 aFunction->SetValue(aChamferShape);
2333 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2335 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2339 // Add thickness reduction elements
2340 // at the three extremities: Left, Right and Incident
2343 if (isTRL || isTRR || isTRI) {
2344 TopoDS_Shape aResShape =
2345 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2346 theRL, theWL, theLtransL, theLthinL,
2347 theRR, theWR, theLtransR, theLthinR,
2348 theRI, theWI, theLtransI, theLthinI,
2350 aFunction->SetValue(aResShape);
2353 catch (Standard_Failure& aFail) {
2354 SetErrorCode(aFail.GetMessageString());
2358 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2359 aSeq->Append(aShape);
2364 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2365 theH, theW, 0., aSeq, gp_Trsf()))
2369 // Get internal group.
2370 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2371 theRR, theLtransR, theRI, theLtransI,
2376 catch (Standard_Failure& aFail) {
2377 SetErrorCode(aFail.GetMessageString());
2381 //Make a Python command
2382 TCollection_AsciiString anEntry, aListRes("[");
2383 // Iterate over the sequence aSeq
2384 Standard_Integer aNbGroups = aSeq->Length();
2385 Standard_Integer i = 1;
2386 for (; i <= aNbGroups; i++) {
2387 Handle(Standard_Transient) anItem = aSeq->Value(i);
2388 if (anItem.IsNull()) continue;
2389 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2390 if (aGroup.IsNull()) continue;
2391 //Make a Python command
2392 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2393 aListRes += anEntry + ", ";
2395 aListRes.Trunc(aListRes.Length() - 2);
2397 GEOM::TPythonDump pd (aFunction);
2399 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2400 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2401 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2402 << theH << ", " << theW << ", " << theHexMesh;
2404 // thickness reduction
2406 pd << ", theRL=" << theRL << ", theWL=" << theWL
2407 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2409 pd << ", theRR=" << theRR << ", theWR=" << theWR
2410 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2412 pd << ", theRI=" << theRI << ", theWI=" << theWI
2413 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2422 //=============================================================================
2424 * MakePipeTShapeChamferWithPosition
2425 * Create a T-shape object with specified caracteristics for the main and
2426 * the incident pipes (radius, width, half-length). A chamfer is created
2427 * on the junction of the pipes.
2428 * The extremities of the main pipe are located on junctions points P1 and P2.
2429 * The extremity of the incident pipe is located on junction point P3.
2430 * \param theR1 Internal radius of main pipe
2431 * \param theW1 Width of main pipe
2432 * \param theL1 Half-length of main pipe
2433 * \param theR2 Internal radius of incident pipe (R2 < R1)
2434 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2435 * \param theL2 Half-length of incident pipe
2436 * \param theH Height of chamfer.
2437 * \param theW Width of chamfer.
2438 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2439 * \param theP1 1st junction point of main pipe
2440 * \param theP2 2nd junction point of main pipe
2441 * \param theP3 Junction point of incident pipe
2442 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2444 //=============================================================================
2445 Handle(TColStd_HSequenceOfTransient)
2446 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2447 (double theR1, double theW1, double theL1,
2448 double theR2, double theW2, double theL2,
2449 double theRL, double theWL, double theLtransL, double theLthinL,
2450 double theRR, double theWR, double theLtransR, double theLthinR,
2451 double theRI, double theWI, double theLtransI, double theLthinI,
2452 double theH, double theW,
2454 Handle(GEOM_Object) theP1,
2455 Handle(GEOM_Object) theP2,
2456 Handle(GEOM_Object) theP3)
2460 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2461 //Add a new shape function with parameters
2462 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2463 if (aFunction.IsNull()) return NULL;
2465 //Check if the function is set correctly
2466 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2468 // Check new position
2469 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2473 AdvancedEngine_IPipeTShape aData(aFunction);
2483 aData.SetHexMesh(theHexMesh);
2485 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2486 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2487 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2489 //Compute the resulting value
2492 if (!GetSolver()->ComputeFunction(aFunction)) {
2493 SetErrorCode("TShape driver failed");
2497 catch (Standard_Failure& aFail) {
2498 SetErrorCode(aFail.GetMessageString());
2503 TopoDS_Shape aShapeShape = aShape->GetValue();
2504 TopTools_IndexedMapOfShape anEdgesIndices;
2505 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2506 // Common edges on external cylinders
2507 Handle(GEOM_Object) box_e;
2509 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2512 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2514 box_e->GetLastFunction()->SetDescription("");
2515 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2516 box_e->GetLastFunction()->SetDescription("");
2518 Handle(TColStd_HSequenceOfInteger) edges_e =
2519 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2520 box_e->GetLastFunction()->SetDescription("");
2522 if (edges_e.IsNull() || edges_e->Length() == 0) {
2523 SetErrorCode("External edges not found");
2526 int nbEdgesInChamfer = 0;
2527 std::list<int> theEdges;
2528 for (int i=1; i<=edges_e->Length();i++) {
2529 int edgeID = edges_e->Value(i);
2530 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2531 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2533 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2534 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2535 nbEdgesInChamfer ++;
2536 theEdges.push_back(edgeID);
2540 if (theHexMesh && nbEdgesInChamfer == 1)
2543 Handle(GEOM_Object) aChamfer;
2545 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2547 catch (Standard_Failure& aFail) {
2548 SetErrorCode(aFail.GetMessageString());
2551 if (aChamfer.IsNull()) {
2552 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2555 aChamfer->GetLastFunction()->SetDescription("");
2557 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2558 aFunction->SetValue(aChamferShape);
2562 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2564 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2568 // Add thickness reduction elements
2569 // at the three extremities: Left, Right and Incident
2572 if (isTRL || isTRR || isTRI) {
2573 TopoDS_Shape aResShape =
2574 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2575 theRL, theWL, theLtransL, theLthinL,
2576 theRR, theWR, theLtransR, theLthinR,
2577 theRI, theWI, theLtransI, theLthinI,
2579 aFunction->SetValue(aResShape);
2582 catch (Standard_Failure& aFail) {
2583 SetErrorCode(aFail.GetMessageString());
2588 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2589 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2590 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2591 aFunction->SetValue(aTrsf_Shape);
2593 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2594 aSeq->Append(aShape);
2599 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2600 theH, theW, 0., aSeq, aTrsf))
2604 // Get internal group.
2605 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2606 theRR, theLtransR, theRI, theLtransI,
2611 catch (Standard_Failure& aFail) {
2612 SetErrorCode(aFail.GetMessageString());
2616 //Make a Python command
2617 TCollection_AsciiString anEntry, aListRes("[");
2618 // Iterate over the sequence aSeq
2619 Standard_Integer aNbGroups = aSeq->Length();
2620 Standard_Integer i = 1;
2621 for (; i <= aNbGroups; i++) {
2622 Handle(Standard_Transient) anItem = aSeq->Value(i);
2623 if (anItem.IsNull()) continue;
2624 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2625 if (aGroup.IsNull()) continue;
2626 //Make a Python command
2627 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2628 aListRes += anEntry + ", ";
2630 aListRes.Trunc(aListRes.Length() - 2);
2632 GEOM::TPythonDump pd (aFunction);
2634 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2635 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2636 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2637 << theH << ", " << theW << ", " << theHexMesh << ", "
2638 << theP1 << ", " << theP2 << ", " << theP3;
2640 // thickness reduction
2642 pd << ", theRL=" << theRL << ", theWL=" << theWL
2643 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2645 pd << ", theRR=" << theRR << ", theWR=" << theWR
2646 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2648 pd << ", theRI=" << theRI << ", theWI=" << theWI
2649 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2658 //=============================================================================
2660 * MakePipeTShapeFillet
2661 * Create a T-shape object with specified caracteristics for the main and
2662 * the incident pipes (radius, width, half-length). A fillet is created
2663 * on the junction of the pipes.
2664 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2665 * \param theR1 Internal radius of main pipe
2666 * \param theW1 Width of main pipe
2667 * \param theL1 Half-length of main pipe
2668 * \param theR2 Internal radius of incident pipe (R2 < R1)
2669 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2670 * \param theL2 Half-length of incident pipe
2671 * \param theRF Radius of curvature of fillet.
2672 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2673 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2675 //=============================================================================
2676 Handle(TColStd_HSequenceOfTransient)
2677 AdvancedEngine_IOperations::MakePipeTShapeFillet
2678 (double theR1, double theW1, double theL1,
2679 double theR2, double theW2, double theL2,
2680 double theRL, double theWL, double theLtransL, double theLthinL,
2681 double theRR, double theWR, double theLtransR, double theLthinR,
2682 double theRI, double theWI, double theLtransI, double theLthinI,
2683 double theRF, bool theHexMesh)
2687 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2688 //Add a new shape function with parameters
2689 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2690 if (aFunction.IsNull()) return NULL;
2692 //Check if the function is set correctly
2693 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2695 AdvancedEngine_IPipeTShape aData(aFunction);
2704 aData.SetHexMesh(theHexMesh);
2706 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2707 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2708 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2710 //Compute the resulting value
2713 if (!GetSolver()->ComputeFunction(aFunction)) {
2714 SetErrorCode("TShape driver failed");
2718 catch (Standard_Failure& aFail) {
2719 SetErrorCode(aFail.GetMessageString());
2724 TopoDS_Shape aShapeShape = aShape->GetValue();
2725 TopTools_IndexedMapOfShape anEdgesIndices;
2726 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2727 // Common edges on external cylinders
2728 Handle(GEOM_Object) box_e;
2730 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2733 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2735 box_e->GetLastFunction()->SetDescription("");
2736 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2737 box_e->GetLastFunction()->SetDescription("");
2739 Handle(TColStd_HSequenceOfInteger) edges_e =
2740 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2741 box_e->GetLastFunction()->SetDescription("");
2743 if (edges_e.IsNull() || edges_e->Length() == 0) {
2744 SetErrorCode("External edges not found");
2747 int nbEdgesInFillet = 0;
2748 std::list<int> theEdges;
2749 for (int i=1; i<=edges_e->Length();i++) {
2750 int edgeID = edges_e->Value(i);
2751 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2752 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2754 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2755 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2757 theEdges.push_back(edgeID);
2761 if (theHexMesh && nbEdgesInFillet == 1)
2765 Handle(GEOM_Object) aFillet;
2767 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2769 catch (Standard_Failure& aFail) {
2770 SetErrorCode(aFail.GetMessageString());
2773 if (aFillet.IsNull()) {
2774 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2775 SetErrorCode(myLocalOperations->GetErrorCode());
2778 aFillet->GetLastFunction()->SetDescription("");
2780 TopoDS_Shape aFilletShape = aFillet->GetValue();
2782 #ifdef FILLET_FIX_TOLERANCE
2783 // VSR: 30/12/2014: temporary workaround about Fillet problem
2785 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2788 GEOMUtils::FixShapeCurves(aFilletShape);
2792 aFunction->SetValue(aFilletShape);
2795 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2796 // the following block, when enabled, leads to partitioning problems
2798 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2799 // BEGIN: Limit tolerances (debug)
2800 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2801 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2802 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2803 aCorr1->GetLastFunction()->SetDescription("");
2804 // END: Limit tolerances (debug)
2805 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2807 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2810 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2812 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2816 // Add thickness reduction elements
2817 // at the three extremities: Left, Right and Incident
2820 if (isTRL || isTRR || isTRI) {
2821 TopoDS_Shape aResShape =
2822 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2823 theRL, theWL, theLtransL, theLthinL,
2824 theRR, theWR, theLtransR, theLthinR,
2825 theRI, theWI, theLtransI, theLthinI,
2827 aFunction->SetValue(aResShape);
2830 catch (Standard_Failure& aFail) {
2831 SetErrorCode(aFail.GetMessageString());
2835 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2836 aSeq->Append(aShape);
2841 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2842 0., 0., theRF, aSeq, gp_Trsf()))
2846 // Get internal group.
2847 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2848 theRR, theLtransR, theRI, theLtransI,
2853 catch (Standard_Failure& aFail) {
2854 SetErrorCode(aFail.GetMessageString());
2858 //Make a Python command
2859 TCollection_AsciiString anEntry, aListRes("[");
2860 // Iterate over the sequence aSeq
2861 Standard_Integer aNbGroups = aSeq->Length();
2862 Standard_Integer i = 1;
2863 for (; i <= aNbGroups; i++) {
2864 Handle(Standard_Transient) anItem = aSeq->Value(i);
2865 if (anItem.IsNull()) continue;
2866 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2867 if (aGroup.IsNull()) continue;
2868 //Make a Python command
2869 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2870 aListRes += anEntry + ", ";
2872 aListRes.Trunc(aListRes.Length() - 2);
2874 GEOM::TPythonDump pd (aFunction);
2876 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2877 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2878 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2879 << theRF << ", " << theHexMesh;
2881 // thickness reduction
2883 pd << ", theRL=" << theRL << ", theWL=" << theWL
2884 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2886 pd << ", theRR=" << theRR << ", theWR=" << theWR
2887 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2889 pd << ", theRI=" << theRI << ", theWI=" << theWI
2890 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2899 //=============================================================================
2901 * MakePipeTShapeFilletWithPosition
2902 * \brief Create a T-shape object with specified caracteristics for the main and
2903 * the incident pipes (radius, width, half-length). A fillet is created
2904 * on the junction of the pipes.
2905 * The extremities of the main pipe are located on junctions points P1 and P2.
2906 * The extremity of the incident pipe is located on junction point P3.
2907 * \param theR1 Internal radius of main pipe
2908 * \param theW1 Width of main pipe
2909 * \param theL1 Half-length of main pipe
2910 * \param theR2 Internal radius of incident pipe (R2 < R1)
2911 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2912 * \param theL2 Half-length of incident pipe
2913 * \param theRF Radius of curvature of fillet
2914 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2915 * \param theP1 1st junction point of main pipe
2916 * \param theP2 2nd junction point of main pipe
2917 * \param theP3 Junction point of incident pipe
2918 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2920 //=============================================================================
2921 Handle(TColStd_HSequenceOfTransient)
2922 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2923 (double theR1, double theW1, double theL1,
2924 double theR2, double theW2, double theL2,
2925 double theRL, double theWL, double theLtransL, double theLthinL,
2926 double theRR, double theWR, double theLtransR, double theLthinR,
2927 double theRI, double theWI, double theLtransI, double theLthinI,
2928 double theRF, bool theHexMesh,
2929 Handle(GEOM_Object) theP1,
2930 Handle(GEOM_Object) theP2,
2931 Handle(GEOM_Object) theP3)
2935 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2936 //Add a new shape function with parameters
2937 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2938 if (aFunction.IsNull()) return NULL;
2940 //Check if the function is set correctly
2941 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2943 // Check new position
2944 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2948 AdvancedEngine_IPipeTShape aData(aFunction);
2957 aData.SetHexMesh(theHexMesh);
2959 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2960 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2961 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2963 //Compute the resulting value
2966 if (!GetSolver()->ComputeFunction(aFunction)) {
2967 SetErrorCode("TShape driver failed");
2971 catch (Standard_Failure& aFail) {
2972 SetErrorCode(aFail.GetMessageString());
2977 TopoDS_Shape aShapeShape = aShape->GetValue();
2978 TopTools_IndexedMapOfShape anEdgesIndices;
2979 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2980 // Common edges on external cylinders
2981 Handle(GEOM_Object) box_e;
2983 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2986 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2988 box_e->GetLastFunction()->SetDescription("");
2989 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2990 box_e->GetLastFunction()->SetDescription("");
2992 Handle(TColStd_HSequenceOfInteger) edges_e =
2993 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2994 box_e->GetLastFunction()->SetDescription("");
2996 if (edges_e.IsNull() || edges_e->Length() == 0) {
2997 SetErrorCode("External edges not found");
3000 int nbEdgesInFillet = 0;
3001 std::list<int> theEdges;
3002 for (int i=1; i<=edges_e->Length();i++) {
3003 int edgeID = edges_e->Value(i);
3004 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3005 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3007 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3008 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3010 theEdges.push_back(edgeID);
3014 if (theHexMesh && nbEdgesInFillet == 1)
3018 Handle(GEOM_Object) aFillet;
3020 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3022 catch (Standard_Failure& aFail) {
3023 SetErrorCode(aFail.GetMessageString());
3026 if (aFillet.IsNull()) {
3027 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3030 aFillet->GetLastFunction()->SetDescription("");
3032 TopoDS_Shape aFilletShape = aFillet->GetValue();
3034 #ifdef FILLET_FIX_TOLERANCE
3035 // VSR: 30/12/2014: temporary workaround about Fillet problem
3037 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3040 GEOMUtils::FixShapeCurves(aFilletShape);
3044 aFunction->SetValue(aFilletShape);
3047 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3048 // the following block, when enabled, leads to partitioning problems
3050 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3051 // BEGIN: Limit tolerances (debug)
3052 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3053 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3054 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3055 aCorr1->GetLastFunction()->SetDescription("");
3056 // END: Limit tolerances (debug)
3057 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3059 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3062 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3064 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3068 // Add thickness reduction elements
3069 // at the three extremities: Left, Right and Incident
3072 if (isTRL || isTRR || isTRI) {
3073 TopoDS_Shape aResShape =
3074 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3075 theRL, theWL, theLtransL, theLthinL,
3076 theRR, theWR, theLtransR, theLthinR,
3077 theRI, theWI, theLtransI, theLthinI,
3079 aFunction->SetValue(aResShape);
3082 catch (Standard_Failure& aFail) {
3083 SetErrorCode(aFail.GetMessageString());
3088 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3089 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3090 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3091 aFunction->SetValue(aTrsf_Shape);
3093 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3094 aSeq->Append(aShape);
3099 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3100 0., 0., theRF, aSeq, aTrsf))
3104 // Get internal group.
3105 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3106 theRR, theLtransR, theRI, theLtransI,
3111 catch (Standard_Failure& aFail) {
3112 SetErrorCode(aFail.GetMessageString());
3116 //Make a Python command
3117 TCollection_AsciiString anEntry, aListRes("[");
3118 // Iterate over the sequence aSeq
3119 Standard_Integer aNbGroups = aSeq->Length();
3120 Standard_Integer i = 1;
3121 for (; i <= aNbGroups; i++) {
3122 Handle(Standard_Transient) anItem = aSeq->Value(i);
3123 if (anItem.IsNull()) continue;
3124 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3125 if (aGroup.IsNull()) continue;
3126 //Make a Python command
3127 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3128 aListRes += anEntry + ", ";
3130 aListRes.Trunc(aListRes.Length() - 2);
3132 GEOM::TPythonDump pd (aFunction);
3134 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3135 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3136 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3137 << theRF << ", " << theHexMesh << ", "
3138 << theP1 << ", " << theP2 << ", " << theP3;
3140 // thickness reduction
3142 pd << ", theRL=" << theRL << ", theWL=" << theWL
3143 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3145 pd << ", theRR=" << theRR << ", theWR=" << theWR
3146 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3148 pd << ", theRI=" << theRI << ", theWI=" << theWI
3149 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3158 //=============================================================================
3160 * This function allows to create a disk already divided into blocks. It can be
3161 * used to create divided pipes for later meshing in hexaedra.
3162 * \param theR Radius of the disk
3163 * \param theRatio Relative size of the central square diagonal against the disk diameter
3164 * \param theOrientation Plane on which the disk will be built
3165 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3166 * \return New GEOM_Object, containing the created shape.
3168 //=============================================================================
3169 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3170 int theOrientation, int thePattern)
3174 if (theOrientation != 1 &&
3175 theOrientation != 2 &&
3176 theOrientation != 3)
3178 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3182 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3184 //Add a new shape function with parameters
3185 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3186 if (aFunction.IsNull()) return NULL;
3188 //Check if the function is set correctly
3189 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3191 AdvancedEngine_IDividedDisk aData (aFunction);
3194 aData.SetRatio(theRatio);
3195 aData.SetOrientation(theOrientation);
3196 aData.SetType(thePattern);
3198 //Compute the resulting value
3201 if (!GetSolver()->ComputeFunction(aFunction)) {
3202 SetErrorCode("DividedDisk driver failed");
3206 catch (Standard_Failure& aFail) {
3207 SetErrorCode(aFail.GetMessageString());
3211 std::string aPatternStr;
3216 aPatternStr = "GEOM.SQUARE";
3219 aPatternStr = "GEOM.HEXAGON";
3223 //Make a Python command
3224 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3231 //=============================================================================
3233 * This function allows to create a disk already divided into blocks. It can be
3234 * used to create divided pipes for later meshing in hexaedra.
3235 * \param theR Radius of the disk
3236 * \param theRatio Relative size of the central square diagonal against the disk diameter
3237 * \return New GEOM_Object, containing the created shape.
3239 //=============================================================================
3240 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3241 Handle(GEOM_Object) theVec,
3249 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3251 //Add a new shape function with parameters
3252 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3253 if (aFunction.IsNull()) return NULL;
3255 //Check if the function is set correctly
3256 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3258 AdvancedEngine_IDividedDisk aData (aFunction);
3260 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3261 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3263 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3265 aData.SetCenter(aRefPnt);
3266 aData.SetVector(aRefVec);
3269 aData.SetRatio(theRatio);
3270 aData.SetType(thePattern);
3272 //Compute the resulting value
3275 if (!GetSolver()->ComputeFunction(aFunction)) {
3276 SetErrorCode("DividedDisk driver failed");
3280 catch (Standard_Failure& aFail) {
3281 SetErrorCode(aFail.GetMessageString());
3285 std::string aPatternStr;
3290 aPatternStr = "GEOM.SQUARE";
3293 aPatternStr = "GEOM.HEXAGON";
3298 //Make a Python command
3299 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3306 //=============================================================================
3308 * Builds a cylinder prepared for hexa meshes
3309 * \param theR Radius of the cylinder
3310 * \param theH Height of the cylinder
3311 * \return New GEOM_Object, containing the created shape.
3313 //=============================================================================
3314 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3321 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3323 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3324 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3326 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3328 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3329 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3330 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3332 std::string aPatternStr;
3337 aPatternStr = "GEOM.SQUARE";
3340 aPatternStr = "GEOM.HEXAGON";
3344 //Make a Python command
3345 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3351 //=============================================================================
3353 * Create a smoothing surface from a set of points
3354 * \param thelPoints list of points or compounds of points
3355 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3356 * \param theDegMax maximum degree of the resulting BSpline surface
3357 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3358 * \return New GEOM_Object, containing the created shape.
3360 //=============================================================================
3361 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3369 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3371 //Add a new shape function with parameters
3372 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3373 if (aFunction.IsNull()) return NULL;
3375 //Check if the function is set correctly
3376 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3378 AdvancedEngine_ISmoothingSurface aData (aFunction);
3380 int aLen = thelPoints.size();
3381 aData.SetLength(aLen);
3383 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3384 for (; it != thelPoints.end(); it++, ind++) {
3385 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3386 if (aRefObj.IsNull()) {
3387 SetErrorCode("NULL point or compound for bSplineFaceShape");
3390 aData.SetPntOrComp(ind, aRefObj);
3393 aData.SetNbMax(theNbMax);
3394 aData.SetDegMax(theDegMax);
3395 aData.SetDMax(theDMax);
3397 //Compute the resulting value
3400 if (!GetSolver()->ComputeFunction(aFunction)) {
3401 SetErrorCode("SmoothingSurface driver failed");
3405 catch (Standard_Failure& aFail) {
3406 SetErrorCode(aFail.GetMessageString());
3410 //Make a Python command
3411 GEOM::TPythonDump pd (aFunction);
3412 pd << aShape << " = geompy.MakeSmoothingSurface([";
3413 it = thelPoints.begin();
3415 while (it != thelPoints.end()) {
3416 pd << ", " << (*it++);
3420 << theDegMax << ", "