1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_Splitter.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMImpl_Gen.hxx"
43 #include "GEOMImpl_Types.hxx"
45 #include "GEOMImpl_IBasicOperations.hxx"
46 #include "GEOMImpl_IBooleanOperations.hxx"
47 #include "GEOMImpl_IShapesOperations.hxx"
48 #include "GEOMImpl_ITransformOperations.hxx"
49 #include "GEOMImpl_IBlocksOperations.hxx"
50 #include "GEOMImpl_I3DPrimOperations.hxx"
51 #include "GEOMImpl_ILocalOperations.hxx"
52 #include "GEOMImpl_IHealingOperations.hxx"
53 #include "GEOMImpl_IGroupOperations.hxx"
54 #include "GEOMImpl_GlueDriver.hxx"
56 #include <TDF_Tool.hxx>
57 #include <TFunction_DriverTable.hxx>
58 #include <TFunction_Driver.hxx>
59 #include <TFunction_Logbook.hxx>
60 #include <TNaming_CopyShape.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRepAlgoAPI_Cut.hxx>
75 #include <BRepAlgoAPI_Fuse.hxx>
76 #include <BRepBuilderAPI_MakeFace.hxx>
77 #include <BRepBuilderAPI_MakeVertex.hxx>
78 #include <BRepBuilderAPI_Transform.hxx>
79 #include <BRepPrimAPI_MakeCone.hxx>
80 #include <BRepPrimAPI_MakeCylinder.hxx>
86 #include <GC_MakeConicalSurface.hxx>
87 #include <Geom_CylindricalSurface.hxx>
89 #include <ShapeAnalysis_Edge.hxx>
93 #include "AdvancedEngine_Types.hxx"
95 #include <Standard_Stream.hxx>
96 #include <Standard_Failure.hxx>
97 #include <StdFail_NotDone.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
101 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
102 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
103 #define THICKNESS "Thickness" //"Epaisseur"
104 #define FLANGE "Flange" // "Collerette"
105 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
106 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
107 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
108 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
110 #define FIND_GROUPS_BY_POINTS 1
112 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
113 // VSR 30/12/2014: macro enabled
114 #define FILLET_FIX_TOLERANCE
116 //=============================================================================
120 //=============================================================================
121 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
122 GEOM_IOperations(theEngine, theDocID)
124 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
125 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
126 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
127 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
128 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
129 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
130 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
131 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
132 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
133 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
136 //=============================================================================
140 //=============================================================================
141 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
143 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
144 delete myBasicOperations;
145 delete myBooleanOperations;
146 delete myShapesOperations;
147 delete myTransformOperations;
148 delete myBlocksOperations;
149 delete my3DPrimOperations;
150 delete myLocalOperations;
151 delete myHealingOperations;
152 delete myGroupOperations;
155 //=============================================================================
159 //=============================================================================
160 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
161 Handle(GEOM_Object) theP1,
162 Handle(GEOM_Object) theP2,
163 Handle(GEOM_Object) theP3)
165 // Old Local Coordinates System oldLCS
167 gp_Pnt P1(-theL1, 0, 0);
168 gp_Pnt P2(theL1, 0, 0);
169 gp_Pnt P3(0, 0, theL2);
171 gp_Dir oldX(gp_Vec(P1, P2));
172 gp_Dir oldZ(gp_Vec(P0, P3));
173 gp_Ax3 oldLCS(P0, oldZ, oldX);
175 // New Local Coordinates System newLCS
176 double LocX, LocY, LocZ;
177 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
178 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
179 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
180 LocX = (newP1.X() + newP2.X()) / 2.;
181 LocY = (newP1.Y() + newP2.Y()) / 2.;
182 LocZ = (newP1.Z() + newP2.Z()) / 2.;
183 gp_Pnt newO(LocX, LocY, LocZ);
185 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
186 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
187 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
190 aTrsf.SetDisplacement(oldLCS, newLCS);
195 //=============================================================================
197 * CheckCompatiblePosition
200 //=============================================================================
201 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
202 Handle(GEOM_Object) theP1,
203 Handle(GEOM_Object) theP2,
204 Handle(GEOM_Object) theP3,
208 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
209 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
210 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
212 double d12 = P1.Distance(P2);
213 double d13 = P1.Distance(P3);
214 double d23 = P2.Distance(P3);
215 // double d2 = newO.Distance(P3);
217 if (Abs(d12) <= Precision::Confusion()) {
218 SetErrorCode("Junctions points P1 and P2 are identical");
221 if (Abs(d13) <= Precision::Confusion()) {
222 SetErrorCode("Junctions points P1 and P3 are identical");
225 if (Abs(d23) <= Precision::Confusion()) {
226 SetErrorCode("Junctions points P2 and P3 are identical");
231 double newL1 = 0.5 * d12;
232 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
234 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
236 if (fabs(newL1 - theL1) > Precision::Approximation()) {
237 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
238 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
239 // std::cerr << "theL1 = newL1" << std::endl;
243 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
249 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
251 if (fabs(newL2 - theL2) > Precision::Approximation()) {
252 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
253 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
257 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
267 //=============================================================================
269 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
271 //=============================================================================
272 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
273 double theR1, double theW1, double theL1,
274 double theR2, double theW2, double theL2,
275 double theH, double theW, double theRF,
276 Handle(TColStd_HSequenceOfTransient) theSeq,
281 if (theShape.IsNull()) return false;
283 TopoDS_Shape aShape = theShape->GetValue();
284 if (aShape.IsNull()) {
285 SetErrorCode("Shape is not defined");
289 gp_Trsf aTrsfInv = aTrsf.Inverted();
291 // int expectedGroups = 0;
292 // if (shapeType == TSHAPE_BASIC)
293 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
294 // expectedGroups = 10;
296 // expectedGroups = 11;
297 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
298 // expectedGroups = 12;
300 double aR1Ext = theR1 + theW1;
301 double aR2Ext = theR2 + theW2;
303 /////////////////////////
304 //// Groups of Faces ////
305 /////////////////////////
308 // Comment the following lines when GetInPlace bug is solved
310 // Workaround of GetInPlace bug
311 // Create a bounding box that fits the shape
312 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
313 aBox->GetLastFunction()->SetDescription("");
314 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
315 aBox->GetLastFunction()->SetDescription("");
316 // Apply transformation to box
317 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
318 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
319 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
321 // Get the shell of the box
322 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
323 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
324 aBox->GetLastFunction()->SetDescription("");
325 aShell->GetLastFunction()->SetDescription("");
326 // Get the common shapes between shell and shape
327 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
328 (theShape, aShell, 1, Standard_False); // MakeCommon
329 if (aCommonCompound.IsNull()) {
330 SetErrorCode(myBooleanOperations->GetErrorCode());
333 aCommonCompound->GetLastFunction()->SetDescription("");
334 // Explode the faces of common shapes => 3 faces
335 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
336 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
337 aCommonCompound->GetLastFunction()->SetDescription("");
338 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
340 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
341 std::list<Handle(GEOM_Object)> aFacesList;
342 for (int j = 1 ; j <= 4 ; j++) {
343 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
344 if (!aFace.IsNull()) {
345 aFace->GetLastFunction()->SetDescription("");
346 aFacesList.push_back(aFace);
349 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
350 if (!aCompoundOfFaces.IsNull()) {
351 aCompoundOfFaces->GetLastFunction()->SetDescription("");
352 aCompoundOfFacesList.push_back(aCompoundOfFaces);
356 if (aCompoundOfFacesList.size() == 3) {
357 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
359 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
360 aCompoundOfFacesList.pop_front();
361 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
362 aCompoundOfFacesList.pop_front();
367 // Uncomment the following lines when GetInPlace bug is solved
369 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
370 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
371 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
372 // aP1->GetLastFunction()->SetDescription("");
373 // aP2->GetLastFunction()->SetDescription("");
374 // aP3->GetLastFunction()->SetDescription("");
375 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
376 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
377 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
378 // aV1->GetLastFunction()->SetDescription("");
379 // aV2->GetLastFunction()->SetDescription("");
380 // aV3->GetLastFunction()->SetDescription("");
381 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
382 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
383 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
384 // aPln1->GetLastFunction()->SetDescription("");
385 // aPln2->GetLastFunction()->SetDescription("");
386 // aPln3->GetLastFunction()->SetDescription("");
388 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
389 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
390 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
391 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
392 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
393 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
394 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
395 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
396 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
400 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
401 if (junctionFaces1.IsNull())
402 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
403 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
404 if (!junctionFaces1.IsNull()) {
405 junctionFaces1->GetLastFunction()->SetDescription("");
406 junctionFaces1->SetName("JUNCTION_FACE_1");
407 theSeq->Append(junctionFaces1);
410 SetErrorCode("Junction face 1 not found");
411 // theSeq->Append(aPln1);
414 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
415 if (junctionFaces2.IsNull())
416 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
417 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
418 if (!junctionFaces2.IsNull()) {
419 junctionFaces2->GetLastFunction()->SetDescription("");
420 junctionFaces2->SetName("JUNCTION_FACE_2");
421 theSeq->Append(junctionFaces2);
424 SetErrorCode("Junction face 2 not found");
425 // theSeq->Append(aPln2);
428 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
429 if (junctionFaces3.IsNull())
430 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
431 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
432 if (!junctionFaces3.IsNull()) {
433 junctionFaces3->GetLastFunction()->SetDescription("");
434 junctionFaces3->SetName("JUNCTION_FACE_3");
435 theSeq->Append(junctionFaces3);
438 SetErrorCode("Junction face 3 not found");
439 // theSeq->Append(aPln3);
442 // Comment the following lines when GetInPlace bug is solved
447 /////////////////////////
448 //// Groups of Edges ////
449 /////////////////////////
450 // Result of propagate
452 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
454 TCollection_AsciiString theDesc = aFunction->GetDescription();
455 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
456 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
457 SetErrorCode("Propagation groups not found");
460 Standard_Integer aNbGroups = aSeqPropagate->Length();
461 // Recover previous description to get rid of Propagate dump
462 aFunction->SetDescription(theDesc);
464 #ifdef FIND_GROUPS_BY_POINTS
465 // BEGIN: new groups search
472 // g / ''..| | |..'' \
474 // .---.--'.. | | | ..'--.---.
475 // |a \ '''...........''' / |
476 // |-------\------' | '------/-------.
481 // ._________________|_________________.
487 // |-----------------|-----------------|
489 // '-----------------'-----------------'
492 // "Thickness" group (a)
493 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
494 aPntA.Transform(aTrsf);
495 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
496 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
497 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
499 // "Circular quarter of pipe" group (b)
500 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
501 aPntB.Transform(aTrsf);
502 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
503 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
504 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
506 // "Circular quarter of pipe" group (c)
507 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
508 aPntC.Transform(aTrsf);
509 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
510 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
511 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
513 // "Main pipe half length" group (d)
514 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
515 aPntD.Transform(aTrsf);
516 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
517 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
518 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
520 // "Incident pipe half length" group (e)
521 double aTol10 = Precision::Confusion() * 10.;
522 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
523 aPntE.Transform(aTrsf);
524 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
525 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
526 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
528 // "Flange" group (f)
529 double aFx = - aR2Ext - aTol10;
530 if (shapeType == TSHAPE_CHAMFER)
532 else if (shapeType == TSHAPE_FILLET)
534 gp_Pnt aPntF (aFx, 0, aR1Ext);
535 aPntF.Transform(aTrsf);
536 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
537 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
538 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
540 // "Chamfer or Fillet" group (g)
541 TopoDS_Shape anEdgeG;
542 if (shapeType == TSHAPE_CHAMFER) {
543 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
544 aPntG.Transform(aTrsf);
545 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
546 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
547 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
549 else if (shapeType == TSHAPE_FILLET) {
550 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
551 aPntG.Transform(aTrsf);
552 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
553 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
554 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
557 for (int i = 1 ; i <= aNbGroups; i++) {
558 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
562 TopoDS_Shape aGroupShape = aGroup->GetValue();
563 TopTools_IndexedMapOfShape anEdgesMap;
564 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
566 if (anEdgesMap.Contains(anEdgeA)) { // a
567 aGroup->SetName("THICKNESS");
568 theSeq->Append(aGroup);
570 else if (anEdgesMap.Contains(anEdgeB)) { // b
571 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
572 theSeq->Append(aGroup);
574 else if (anEdgesMap.Contains(anEdgeC)) { // c
575 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
576 theSeq->Append(aGroup);
578 else if (anEdgesMap.Contains(anEdgeD)) { // d
579 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
580 theSeq->Append(aGroup);
582 else if (anEdgesMap.Contains(anEdgeE)) { // e
583 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
584 theSeq->Append(aGroup);
586 else if (anEdgesMap.Contains(anEdgeF)) { // f
587 aGroup->SetName("FLANGE");
588 theSeq->Append(aGroup);
590 else if (shapeType == TSHAPE_CHAMFER) { // g
591 if (anEdgesMap.Contains(anEdgeG)) {
592 aGroup->SetName("CHAMFER");
593 theSeq->Append(aGroup);
596 else if (shapeType == TSHAPE_FILLET) { // g
597 if (anEdgesMap.Contains(anEdgeG)) {
598 aGroup->SetName("FILLET");
599 theSeq->Append(aGroup);
605 // END: new groups search
608 bool circularFoundAndAdded = false;
609 bool circularFound10 = false;
610 bool incidentPipeFound = false;
611 bool mainPipeFound = false;
612 bool mainPipeFoundAndAdded = false;
613 bool radialFound =false;
614 bool flangeFound = false;
615 bool flangeFoundAndAdded = false;
616 bool chamferOrFilletFound = false;
618 for (int i = 1 ; i <= aNbGroups; i++) {
621 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
625 TopoDS_Shape aGroupShape = aGroup->GetValue();
626 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
627 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
629 TopTools_IndexedMapOfShape anEdgesMap;
630 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
631 Standard_Integer nbEdges = anEdgesMap.Extent();
633 if (shapeType == TSHAPE_BASIC) {
634 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
636 aGroup->SetName("THICKNESS");
638 else if (nbEdges == 6) {
639 if (!circularFoundAndAdded) {
640 circularFoundAndAdded = true;
642 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
645 else if (nbEdges == 8) {
646 incidentPipeFound = true;
647 mainPipeFound = false;
651 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
653 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
654 double x=aP.X(), y=aP.Y(), z=aP.Z();
657 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
658 (Abs(y) > aR2Ext + Precision::Confusion())) {
659 incidentPipeFound = false;
662 if ( z < -Precision::Confusion()) {
663 // length of main pipe
664 mainPipeFound = true;
665 if (!mainPipeFoundAndAdded) {
666 mainPipeFoundAndAdded = true;
668 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
672 else if (Abs(x) > (theL1-Precision::Confusion())) {
673 // discretisation circulaire
675 if (!circularFoundAndAdded) {
676 circularFoundAndAdded = true;
678 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
683 if (incidentPipeFound) {
685 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
687 if (!addGroup && (!incidentPipeFound &&
691 // Flange (collerette)
694 aGroup->SetName("FLANGE");
700 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
701 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
703 aGroup->SetName("THICKNESS");
705 else if ((nbEdges == 10) || (nbEdges == 6)) {
706 if (!circularFoundAndAdded) {
708 circularFoundAndAdded = true;
709 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
711 circularFound10 = true;
714 else if (!circularFound10 && nbEdges == 10) {
715 circularFound10 = true;
717 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
720 else if (nbEdges == 8) {
721 incidentPipeFound = true;
722 mainPipeFound = true;
725 bool isNearZ0 = false;
726 bool isBelowZ0 = false;
728 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
730 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
731 double x=aP.X(), y=aP.Y(), z=aP.Z();
733 // tuy_princ_long_avant & tuy_princ_long_apres
734 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
735 // ((y <= aR1Ext + Precision::Confusion()) ||
736 // (y <= -(aR1Ext + Precision::Confusion())) ||
737 // (y <= theR1 + Precision::Confusion()) ||
738 // (y == -(theR1 + Precision::Confusion()))));
739 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
740 (fabs(y) > theR1 - Precision::Confusion() ||
741 fabs(y) < Precision::Confusion()));
744 mainPipeFound = false;
748 //if (z < Precision::Confusion() && !isMain) {
749 // flangeFound = true;
750 // if (!flangeFoundAndAdded) {
751 // flangeFoundAndAdded = true;
753 // aGroup->SetName("FLANGE");
756 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
757 if (z < - Precision::Confusion()) isBelowZ0 = true;
760 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
761 (Abs(y) > aR2Ext + Precision::Confusion())) {
762 incidentPipeFound = false;
768 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
770 if (incidentPipeFound) {
772 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
774 if (isNearZ0 && !isBelowZ0) {
776 if (!flangeFoundAndAdded) {
777 flangeFoundAndAdded = true;
779 aGroup->SetName("FLANGE");
782 if (!addGroup && (!incidentPipeFound &&
785 !chamferOrFilletFound)) {
787 chamferOrFilletFound = true;
788 if (shapeType == TSHAPE_CHAMFER)
789 aGroup->SetName("CHAMFER");
791 aGroup->SetName("FILLET");
797 // Add group to the list
799 theSeq->Append(aGroup);
807 //=============================================================================
809 * Return faces that are laying on surface.
811 //=============================================================================
812 bool AdvancedEngine_IOperations::GetFacesOnSurf
813 (const TopoDS_Shape &theShape,
814 const Handle_Geom_Surface& theSurface,
815 const Standard_Real theTolerance,
816 TopTools_ListOfShape &theFaces)
818 GEOMAlgo_FinderShapeOn1 aFinder;
820 aFinder.SetShape(theShape);
821 aFinder.SetTolerance(theTolerance);
822 aFinder.SetSurface(theSurface);
823 aFinder.SetShapeType(TopAbs_FACE);
824 aFinder.SetState(GEOMAlgo_ST_ON);
826 // Sets the minimal number of inner points for the faces that do not have own
827 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
829 aFinder.SetNbPntsMin(3);
830 // Sets the maximal number of inner points for edges or faces.
831 // It is usefull for the cases when this number is very big (e.g =2000) to improve
832 // the performance. If this value =0, all inner points will be taken into account.
834 aFinder.SetNbPntsMax(100);
837 // Interprete results
838 Standard_Integer iErr = aFinder.ErrorStatus();
839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
841 MESSAGE(" iErr : " << iErr);
842 TCollection_AsciiString aMsg (" iErr : ");
843 aMsg += TCollection_AsciiString(iErr);
847 Standard_Integer iWrn = aFinder.WarningStatus();
848 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
850 MESSAGE(" *** iWrn : " << iWrn);
853 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
854 TopTools_ListIteratorOfListOfShape anIter (aListRes);
856 for (; anIter.More(); anIter.Next()) {
857 theFaces.Append(anIter.Value());
863 //=============================================================================
865 * Creates and returns conical face.
867 //=============================================================================
868 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
869 (const gp_Ax2 &theAxis,
870 const double theRadius,
871 const double theRadiusThin,
872 const double theHeight,
873 const gp_Trsf &theTrsf)
875 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
876 TopoDS_Shape aResult;
879 if (aMkCone.IsDone()) {
880 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
882 for (; anExp.More(); anExp.Next()) {
883 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
885 if (aFace.IsNull() == Standard_False) {
886 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
888 if (anAdaptor.GetType() == GeomAbs_Cone) {
889 // This is a conical face. Transform and return it.
890 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
892 aResult = aTransf.Shape();
902 //=============================================================================
904 * Generate the internal group of a Pipe T-Shape
906 //=============================================================================
907 bool AdvancedEngine_IOperations::MakeInternalGroup
908 (const Handle(GEOM_Object) &theShape,
909 const double theR1, const double theLen1,
910 const double theR2, const double theLen2,
911 const double theRL, double theTransLenL,
912 const double theRR, double theTransLenR,
913 const double theRI, double theTransLenI,
914 const Handle(TColStd_HSequenceOfTransient) &theSeq,
915 const gp_Trsf &theTrsf)
919 if (theShape.IsNull()) {
923 TopoDS_Shape aShape = theShape->GetValue();
925 if (aShape.IsNull()) {
926 SetErrorCode("Shape is not defined");
931 Standard_Real aMaxTol = -RealLast();
932 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
934 for (; anExp.More(); anExp.Next()) {
935 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
937 if (aVertex.IsNull() == Standard_False) {
938 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
940 if (aTol > aMaxTol) {
946 // Construct internal surfaces.
947 Standard_Integer i = 0;
948 const Standard_Integer aMaxNbSurf = 5;
949 Handle(Geom_Surface) aSurface[aMaxNbSurf];
950 TopTools_ListOfShape aConicalFaces;
951 Standard_Real aTolConf = Precision::Confusion();
953 // 1. Construct the internal surface of main pipe.
954 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
955 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
957 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
959 // 2. Construct the internal surface of incident pipe.
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
962 // 3. Construct the internal surface of left reduction pipe.
963 if (theRL > aTolConf) {
964 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
966 if (theTransLenL > aTolConf) {
967 // 3.1. Construct the internal surface of left transition pipe.
968 gp_Pnt aPLeft (-theLen1, 0., 0.);
969 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
970 TopoDS_Shape aConeLeft =
971 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
973 if (aConeLeft.IsNull() == Standard_False) {
974 aConicalFaces.Append(aConeLeft);
979 // 4. Construct the internal surface of right reduction pipe.
980 if (theRR > aTolConf) {
981 // There is no need to construct another cylinder of the same radius. Skip it.
982 if (Abs(theRR - theRL) > aTolConf) {
983 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
986 if (theTransLenL > aTolConf) {
987 // 4.1. Construct the internal surface of right transition pipe.
988 gp_Pnt aPRight (theLen1, 0., 0.);
989 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
990 TopoDS_Shape aConeRight =
991 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
993 if (aConeRight.IsNull() == Standard_False) {
994 aConicalFaces.Append(aConeRight);
999 // 5. Construct the internal surface of incident reduction pipe.
1000 if (theRI > aTolConf) {
1001 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1003 if (theTransLenI > aTolConf) {
1004 // 5.1. Construct the internal surface of incident transition pipe.
1005 gp_Pnt aPInci (0., 0., theLen2);
1006 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1007 TopoDS_Shape aConeInci =
1008 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1010 if (aConeInci.IsNull() == Standard_False) {
1011 aConicalFaces.Append(aConeInci);
1016 // Get faces that are laying on cylindrical surfaces.
1017 TopTools_ListOfShape aFaces;
1018 gp_Trsf anInvTrsf = theTrsf.Inverted();
1020 for (i = 0; i < aMaxNbSurf; i++) {
1021 if (aSurface[i].IsNull()) {
1025 aSurface[i]->Transform(theTrsf);
1027 TopTools_ListOfShape aLocalFaces;
1029 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1034 // Check if the result contains outer cylinders.
1035 // It is required for main and incident pipes.
1036 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1038 while (anIter.More()) {
1039 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1040 Standard_Boolean isInside = Standard_False;
1042 // Get a vertex from this shape
1044 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1046 if (aVtx.IsNull() == Standard_False) {
1047 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1049 aPnt.Transform(anInvTrsf);
1052 // Check if the point is inside the main pipe.
1053 isInside = (Abs(aPnt.X()) <= theLen1);
1055 // Check if the point is inside the incident pipe.
1056 isInside = (aPnt.Z() <= theLen2);
1065 // Remove this face.
1066 aLocalFaces.Remove(anIter);
1071 aFaces.Append(aLocalFaces);
1074 // Get faces that are laying on conical faces.
1075 if (aConicalFaces.IsEmpty() == Standard_False) {
1076 Handle(GEOM_Object) aCone =
1077 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1078 Handle(GEOM_Function) aFunction =
1079 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1080 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1081 Handle(GEOM_Object) aConeFromShape;
1083 for (; aFIter.More(); aFIter.Next()) {
1084 aFunction->SetValue(aFIter.Value());
1085 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1087 if (aConeFromShape.IsNull() == Standard_False) {
1088 aConeFromShape->GetLastFunction()->SetDescription("");
1089 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1090 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1092 for (; anExp.More(); anExp.Next()) {
1093 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1095 if (aConeFace.IsNull() == Standard_False) {
1096 aFaces.Append(aConeFace);
1103 // Create a group of internal faces.
1104 if (aFaces.IsEmpty() == Standard_False) {
1105 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1107 if (aGroup.IsNull() == Standard_False) {
1108 aGroup->GetLastFunction()->SetDescription("");
1109 aGroup->SetName("INTERNAL_FACES");
1111 TopTools_IndexedMapOfShape anIndices;
1112 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1114 TopExp::MapShapes(aShape, anIndices);
1116 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1118 for (; anIter.More(); anIter.Next()) {
1119 const TopoDS_Shape &aFace = anIter.Value();
1120 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1123 aSeqIDs->Append(anIndex);
1127 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1128 aGroup->GetLastFunction()->SetDescription("");
1129 theSeq->Append(aGroup);
1138 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1139 double theR1, double theW1, double theL1,
1140 double theR2, double theW2, double theL2,
1141 double theH, double theW,
1142 double theRF, bool isNormal)
1146 // Build tools for partition operation:
1147 // 1 face and 2 planes
1149 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1150 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1151 Handle(GEOM_Object) chan_racc;
1152 Handle(GEOM_Object) vi1, vi2;
1153 Handle(GEOM_Object) Te3;
1157 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1158 Vector_Z->GetLastFunction()->SetDescription("");
1161 double aSize = 2*(theL1 + theL2);
1162 double aR1Ext = theR1 + theW1;
1163 double aR2Ext = theR2 + theW2;
1164 double theVertCylinderRadius = aR2Ext + theW + theRF;
1165 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1167 // Common edges on internal cylinder
1168 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1169 box_i->GetLastFunction()->SetDescription("");
1170 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1171 box_i->GetLastFunction()->SetDescription("");
1173 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1174 TCollection_AsciiString theDesc = aFunction->GetDescription();
1175 Handle(TColStd_HSequenceOfTransient) edges_i =
1176 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1177 // Recover previous description to get rid of Propagate dump
1178 aFunction->SetDescription(theDesc);
1179 if (edges_i.IsNull() || edges_i->Length() == 0) {
1180 SetErrorCode("Internal edges not found");
1183 for (int i=1; i<=edges_i->Length();i++) {
1184 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1185 anObj->GetLastFunction()->SetDescription("");
1187 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1189 // search for vertices located on both internal pipes
1190 aFunction = theShape->GetLastFunction();
1191 theDesc = aFunction->GetDescription();
1192 Handle(TColStd_HSequenceOfTransient) vertices_i =
1193 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1194 // Recover previous description to get rid of Propagate dump
1195 aFunction->SetDescription(theDesc);
1196 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1197 SetErrorCode("Internal vertices not found");
1201 double d1min = theR2+theW2, d2min=theR2+theW2;
1202 for (int i = 1; i <= vertices_i->Length(); i++) {
1203 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1204 v->GetLastFunction()->SetDescription("");
1205 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1206 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1207 if (Abs(aP.X()) <= Precision::Confusion()) {
1208 if (Abs(aP.Y()) < d1min) {
1210 d1min = Abs(aP.Y());
1212 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1213 if (Abs(aP.X()) < d2min) {
1215 d2min = Abs(aP.X());
1219 if (vi1.IsNull() || vi2.IsNull()) {
1220 SetErrorCode("Cannot find internal intersection vertices");
1224 std::list<Handle(GEOM_Object)> theShapes;
1227 Handle(GEOM_Object) ve1, ve2;
1228 TopoDS_Vertex vertex1, vertex2;
1230 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1231 box_e->GetLastFunction()->SetDescription("");
1232 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1233 box_e->GetLastFunction()->SetDescription("");
1235 // search for vertices located on both external pipes
1236 aFunction = theShape->GetLastFunction();
1237 theDesc = aFunction->GetDescription();
1238 Handle(TColStd_HSequenceOfTransient) vertices_e =
1239 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1240 // Recover previous description to get rid of Propagate dump
1241 aFunction->SetDescription(theDesc);
1242 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1243 SetErrorCode("External vertices not found");
1247 double d1max = 0, d2max = 0;
1248 for (int i = 1; i <= vertices_e->Length(); i++) {
1249 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1250 v->GetLastFunction()->SetDescription("");
1251 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1252 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1253 if (Abs(aP.X()) <= Precision::Confusion()) {
1254 if (Abs(aP.Y()) > d1max) {
1257 d1max = Abs(aP.Y());
1259 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1260 if (Abs(aP.X()) > d2max) {
1263 d2max = Abs(aP.X());
1267 if (ve1.IsNull() || ve2.IsNull()) {
1268 SetErrorCode("Cannot find external intersection vertices");
1271 Handle(GEOM_Object) edge_e1, edge_e2;
1273 // Common edges on external cylinder
1274 aFunction = theShape->GetLastFunction();
1275 theDesc = aFunction->GetDescription();
1276 Handle(TColStd_HSequenceOfTransient) edges_e =
1277 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1278 // Recover previous description to get rid of Propagate dump
1279 aFunction->SetDescription(theDesc);
1280 if (edges_e.IsNull() || edges_e->Length() == 0) {
1281 SetErrorCode("External edges not found");
1284 ShapeAnalysis_Edge sae;
1285 for (int i=1; i<=edges_e->Length();i++) {
1286 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1287 anObj->GetLastFunction()->SetDescription("");
1288 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1289 if ( !anEdge.IsNull() &&
1290 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1291 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1292 arete_intersect_ext = anObj;
1296 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1297 if (edge_e1.IsNull()) {
1298 SetErrorCode("Edge 1 could not be built");
1302 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1303 if (edge_e2.IsNull()) {
1304 SetErrorCode("Edge 2 could not be built");
1308 edge_e1->GetLastFunction()->SetDescription("");
1309 edge_e2->GetLastFunction()->SetDescription("");
1311 std::list<Handle(GEOM_Object)> edge_e_elist;
1312 edge_e_elist.push_back(arete_intersect_int);
1313 edge_e_elist.push_back(edge_e1);
1314 edge_e_elist.push_back(arete_intersect_ext);
1315 edge_e_elist.push_back(edge_e2);
1316 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1317 if (wire_t.IsNull()) {
1318 SetErrorCode("Impossible to build wire");
1321 wire_t->GetLastFunction()->SetDescription("");
1322 face_t = myShapesOperations->MakeFace(wire_t, false);
1323 if (face_t.IsNull()) {
1324 SetErrorCode("Impossible to build face");
1327 face_t->GetLastFunction()->SetDescription("");
1329 theShapes.push_back(theShape);
1330 theShapes.push_back(vi1);
1331 theShapes.push_back(vi2);
1332 theShapes.push_back(ve1);
1333 theShapes.push_back(ve2);
1334 theShapes.push_back(edge_e1);
1335 theShapes.push_back(edge_e2);
1336 theShapes.push_back(wire_t);
1337 theShapes.push_back(face_t);
1340 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1341 int idP1, idP2, idP3, idP4;
1344 std::vector<int> LX;
1345 std::vector<int> LY;
1346 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1347 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1348 box_e->GetLastFunction()->SetDescription("");
1349 box_e = myTransformOperations->TranslateDXDYDZ
1350 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1351 box_e->GetLastFunction()->SetDescription("");
1353 aFunction = theShape->GetLastFunction();
1354 theDesc = aFunction->GetDescription();
1355 Handle(TColStd_HSequenceOfTransient) extremVertices =
1356 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1357 // Recover previous description to get rid of Propagate dump
1358 aFunction->SetDescription(theDesc);
1360 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1362 SetErrorCode("Vertices on chamfer not found");
1364 SetErrorCode("Vertices on fillet not found");
1368 theShapes.push_back(theShape);
1369 theShapes.push_back(box_e);
1370 if (extremVertices->Length() != 6) {
1371 // for (int i=1; i<=extremVertices->Length(); i++){
1372 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1374 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1375 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1376 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1377 SetErrorCode("Bad number of vertices on chamfer found");
1381 for (int i=1; i<=extremVertices->Length(); i++){
1382 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1383 aV->GetLastFunction()->SetDescription("");
1384 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1386 if (Abs(aP.X()) <= Precision::Confusion()) {
1387 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1389 if (aP.Z()-ZX > Precision::Confusion()) {
1396 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1398 if (aP.Z() - ZY > Precision::Confusion()) {
1409 if (LX.at(0) == PZX)
1412 if (LY.at(0) == PZY)
1415 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1416 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1417 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1418 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1420 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1421 if (Cote_1.IsNull()) {
1422 SetErrorCode("Impossible to build edge in thickness");
1425 Cote_1->GetLastFunction()->SetDescription("");
1427 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1428 if (Cote_2.IsNull()) {
1429 SetErrorCode("Impossible to build edge in thickness");
1432 Cote_2->GetLastFunction()->SetDescription("");
1434 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1435 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1436 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1437 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1438 if (edge_chan_princ.IsNull()) {
1439 SetErrorCode("Impossible to find edge on main pipe");
1442 edge_chan_princ->GetLastFunction()->SetDescription("");
1444 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1445 if (edge_chan_inc.IsNull()) {
1446 SetErrorCode("Impossible to find edge on incident pipe");
1449 edge_chan_inc->GetLastFunction()->SetDescription("");
1451 std::list<Handle(GEOM_Object)> edgeList1;
1452 edgeList1.push_back(edge_chan_princ);
1453 edgeList1.push_back(Cote_1);
1454 edgeList1.push_back(arete_intersect_int);
1455 edgeList1.push_back(Cote_2);
1457 // std::cerr << "Creating wire 1" << std::endl;
1458 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1459 if (wire_t.IsNull()) {
1460 SetErrorCode("Impossible to build wire");
1463 wire_t->GetLastFunction()->SetDescription("");
1465 // std::cerr << "Creating face 1" << std::endl;
1466 face_t = myShapesOperations->MakeFace(wire_t, false);
1467 if (face_t.IsNull()) {
1468 SetErrorCode("Impossible to build face");
1471 face_t->GetLastFunction()->SetDescription("");
1472 theShapes.push_back(face_t);
1474 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1475 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1476 double deltaZ = aP2.Z() - aP5.Z();
1477 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1478 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1479 if (P5bis.IsNull()) {
1480 SetErrorCode("Impossible to translate vertex");
1483 P5bis->GetLastFunction()->SetDescription("");
1485 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1486 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1487 deltaZ = aP4.Z() - aP6.Z();
1488 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1489 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1490 if (P6bis.IsNull()) {
1491 SetErrorCode("Impossible to translate vertex");
1494 P6bis->GetLastFunction()->SetDescription("");
1496 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1497 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1498 if (Cote_3.IsNull()) {
1499 SetErrorCode("Impossible to build edge in thickness");
1502 Cote_3->GetLastFunction()->SetDescription("");
1504 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1505 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1506 if (Cote_4.IsNull()) {
1507 SetErrorCode("Impossible to build edge in thickness");
1510 Cote_4->GetLastFunction()->SetDescription("");
1512 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1513 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1514 if (Cote_4.IsNull()) {
1515 SetErrorCode("Impossible to build edge in thickness");
1518 Cote_5->GetLastFunction()->SetDescription("");
1520 //std::list<Handle(GEOM_Object)> edgeList2;
1521 //edgeList2.push_back(edge_chan_inc);
1522 //edgeList2.push_back(Cote_3);
1523 //edgeList2.push_back(Cote_5);
1524 //edgeList2.push_back(Cote_4);
1525 // std::cerr << "Creating wire 2" << std::endl;
1526 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1527 //if (wire_t2.IsNull()) {
1528 // SetErrorCode("Impossible to build wire");
1531 //wire_t2->GetLastFunction()->SetDescription("");
1532 // std::cerr << "Creating face 2" << std::endl;
1533 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1535 // Mantis issue 0021682
1536 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1537 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1538 if (face_t2.IsNull()) {
1539 SetErrorCode("Impossible to build face");
1542 face_t2->GetLastFunction()->SetDescription("");
1543 theShapes.push_back(face_t2);
1547 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1548 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1549 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1550 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1551 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1552 aP0->GetLastFunction()->SetDescription("");
1553 aVZ->GetLastFunction()->SetDescription("");
1554 aVXZ->GetLastFunction()->SetDescription("");
1555 aPlnOZ->GetLastFunction()->SetDescription("");
1556 aPlnOXZ->GetLastFunction()->SetDescription("");
1557 theShapes.push_back(aPlnOZ);
1558 theShapes.push_back(aPlnOXZ);
1561 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1562 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1563 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1564 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1565 Handle(TColStd_HArray1OfInteger) theMaterials;
1567 partitionShapes->Append(theShape);
1568 theTools->Append(aPlnOZ);
1569 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1570 theTools->Append(aPlnOXZ);
1571 theTools->Append(face_t);
1573 theTools->Append(face_t2);
1575 Te3 = myBooleanOperations->MakePartition
1576 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1577 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1579 SetErrorCode("Impossible to build partition of TShape");
1582 Te3->GetLastFunction()->SetDescription("");
1584 // Last verification: result should be a block
1585 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1586 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1587 SetErrorCode("TShape is not a compound of block");
1591 // // BEGIN Compound of created shapes - Only for debug purpose
1592 // theShapes.clear();
1593 // theShapes.push_back(theShape);
1594 // theShapes.push_back(aPlnOZ);
1595 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1596 // theShapes.push_back(aPlnOXZ);
1597 // theShapes.push_back(face_t);
1599 // theShapes.push_back(face_t2);
1601 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1602 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1603 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1604 // // END Compound of created shapes - Only for debug purpose
1606 TopoDS_Shape aShape = Te3->GetValue();
1607 theShape->GetLastFunction()->SetValue(aShape);
1609 catch (Standard_Failure) {
1610 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1611 SetErrorCode(aFail->GetMessageString());
1619 // Mirror and glue faces
1620 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1621 double theR1, double theW1, double theL1,
1622 double theR2, double theW2, double theL2)
1627 double aSize = 2*(theL1 + theL2);
1628 double aR1Ext = theR1 + theW1;
1631 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1632 aP0->GetLastFunction()->SetDescription("");
1633 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1634 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1635 aVX->GetLastFunction()->SetDescription("");
1636 aVY->GetLastFunction()->SetDescription("");
1637 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1638 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1639 aPlane_OX->GetLastFunction()->SetDescription("");
1640 aPlane_OY->GetLastFunction()->SetDescription("");
1642 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1644 SetErrorCode("Impossible to build mirror of quarter TShape");
1648 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1650 SetErrorCode("Impossible to build mirror of half TShape");
1654 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1656 SetErrorCode("Impossible to build mirror of half TShape");
1660 std::list<Handle(GEOM_Object)> aShapesList;
1661 aShapesList.push_back(theShape);
1662 aShapesList.push_back(Te4);
1663 aShapesList.push_back(Te5);
1664 aShapesList.push_back(Te6);
1665 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1667 SetErrorCode("Impossible to build compound");
1671 // Copy source shape
1672 TopoDS_Shape aShapeCopy;
1673 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1674 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1676 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1677 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1679 SetErrorCode("Impossible to glue faces of TShape");
1683 TopoDS_Shape aShape = Te8->GetValue();
1684 BRepCheck_Analyzer anAna (aShape, Standard_True);
1686 if (!anAna.IsValid()) {
1687 // Try to do gluing with the tolerance equal to maximal
1688 // tolerance of vertices of the source shape.
1689 Standard_Real aTolMax = -RealLast();
1691 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1692 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1693 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1695 if (aTol > aTolMax) {
1701 Te7->GetLastFunction()->SetValue(aShapeCopy);
1702 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1705 SetErrorCode("Impossible to glue faces of TShape");
1709 aShape = Te8->GetValue();
1713 theShape->GetLastFunction()->SetValue(aShape);
1715 Te4->GetLastFunction()->SetDescription("");
1716 Te5->GetLastFunction()->SetDescription("");
1717 Te6->GetLastFunction()->SetDescription("");
1718 Te7->GetLastFunction()->SetDescription("");
1719 Te8->GetLastFunction()->SetDescription("");
1725 //=======================================================================
1726 //function : MakePipeTShapeThicknessReduction
1727 //purpose : Static method. Add thiskness reduction elements at the three
1728 // open ends of the T-Shape.
1729 //=======================================================================
1730 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1731 (TopoDS_Shape theShape,
1732 double r1, double w1, double l1,
1733 double r2, double w2, double l2,
1734 double rL, double wL, double ltransL, double lthinL,
1735 double rR, double wR, double ltransR, double lthinR,
1736 double rI, double wI, double ltransI, double lthinI,
1737 bool fuseReductions)
1739 // Add thickness reduction elements
1740 // at the three extremities: Left, Right and Incident
1742 // ---------------------.
1744 // ---------------------. \
1745 // ^ \ '-----------------.
1747 // | '-----------------'
1749 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1752 TopoDS_Shape aResult = theShape;
1753 double aTol = Precision::Confusion();
1755 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1757 // Left reduction (rL, wL, ltransL, lthinL)
1758 if (rL > aTol && wL > aTol && ltransL > aTol) {
1759 gp_Pnt aPLeft (-l1, 0, 0);
1760 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1761 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1762 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1764 if (fuseReductions) {
1765 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1766 if (!fuseL.IsDone())
1767 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1768 aResult = fuseL.Shape();
1775 B.Add(C, aReductionLeft);
1781 if (rR > aTol && wR > aTol && ltransR > aTol) {
1782 gp_Pnt aPRight (l1, 0, 0);
1783 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1784 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1785 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1787 if (fuseReductions) {
1788 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1789 if (!fuseR.IsDone())
1790 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1791 aResult = fuseR.Shape();
1798 B.Add(C, aReductionRight);
1803 // Incident reduction
1804 if (rI > aTol && wI > aTol && ltransI > aTol) {
1805 gp_Pnt aPInci (0, 0, l2);
1806 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1807 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1808 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1810 if (fuseReductions) {
1811 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1812 if (!fuseInci.IsDone())
1813 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1814 aResult = fuseInci.Shape();
1821 B.Add(C, aReductionInci);
1826 // Get rid of extra compounds
1827 TopTools_ListOfShape listShapeRes;
1828 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1829 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1831 if (!fuseReductions && listShapeRes.Extent() > 1) {
1832 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1837 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1838 for (; itSub.More(); itSub.Next())
1839 B.Add(C, itSub.Value());
1842 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1848 //=======================================================================
1849 //function : MakeThicknessReduction
1850 //purpose : Static method. Create one thickness reduction element.
1851 //=======================================================================
1852 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1853 const double R, const double W,
1854 const double Rthin, const double Wthin,
1855 const double Ltrans, const double Lthin,
1858 double aTol = Precision::Confusion();
1859 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1860 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1862 bool isThinPart = (Lthin > aTol);
1867 // ^ \ '-----------------.
1869 // | '-----------------'
1871 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1874 double RExt = R + W;
1875 double RthinExt = Rthin + Wthin;
1877 gp_Dir aNormal = theAxes.Direction();
1878 gp_Dir anXDir = theAxes.XDirection();
1879 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1880 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1882 // Build the transition part
1883 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1884 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1887 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1888 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1889 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1891 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1892 TopoDS_Shape aReduction = cut1.Shape();
1894 // Build the thin part, if required
1895 TopoDS_Shape aThinPart;
1897 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1898 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1901 if (!CExt.IsDone() || !CInt.IsDone())
1902 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1903 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1905 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1906 aThinPart = cut2.Shape();
1912 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1913 if (!fuse1.IsDone())
1914 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1915 aReduction = fuse1.Shape();
1919 // Partition the reduction on blocks
1920 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1921 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1922 gp_Pln aPln1 (anAxesPln1);
1923 gp_Pln aPln2 (anAxesPln2);
1924 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1925 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1926 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1928 GEOMAlgo_Splitter PS;
1929 PS.AddArgument(aReduction);
1931 PS.AddArgument(aThinPart);
1934 PS.SetLimit(TopAbs_SOLID);
1937 aReduction = PS.Shape();
1943 //=============================================================================
1946 * \brief Create a T-shape object with specified caracteristics for the main and
1947 * the incident pipes (radius, width, half-length).
1948 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1949 * \param theR1 Internal radius of main pipe
1950 * \param theW1 Width of main pipe
1951 * \param theL1 Half-length of main pipe
1952 * \param theR2 Internal radius of incident pipe (R2 < R1)
1953 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1954 * \param theL2 Half-length of incident pipe
1955 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1956 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1958 //=============================================================================
1959 Handle(TColStd_HSequenceOfTransient)
1960 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1961 double theR2, double theW2, double theL2,
1962 double theRL, double theWL, double theLtransL, double theLthinL,
1963 double theRR, double theWR, double theLtransR, double theLthinR,
1964 double theRI, double theWI, double theLtransI, double theLthinI,
1967 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1970 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1972 //Add a new shape function with parameters
1973 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1974 if (aFunction.IsNull()) return NULL;
1976 //Check if the function is set correctly
1977 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1979 AdvancedEngine_IPipeTShape aData (aFunction);
1987 aData.SetHexMesh(theHexMesh);
1989 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1990 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1991 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1993 //Compute the resulting value
1996 if (!GetSolver()->ComputeFunction(aFunction)) {
1997 SetErrorCode("TShape driver failed");
2002 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2004 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2008 if (isTRL || isTRR || isTRI) {
2009 // Add thickness reduction elements
2010 // at the three extremities: Left, Right and Incident
2011 TopoDS_Shape aResShape =
2012 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2013 theRL, theWL, theLtransL, theLthinL,
2014 theRR, theWR, theLtransR, theLthinR,
2015 theRI, theWI, theLtransI, theLthinI,
2017 aFunction->SetValue(aResShape);
2020 catch (Standard_Failure) {
2021 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2022 SetErrorCode(aFail->GetMessageString());
2026 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2027 aSeq->Append(aShape);
2032 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2033 0., 0., 0., aSeq, gp_Trsf()))
2037 // Get internal group.
2038 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2039 theRR, theLtransR, theRI, theLtransI,
2044 catch (Standard_Failure) {
2045 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2046 SetErrorCode(aFail->GetMessageString());
2050 //Make a Python command
2051 TCollection_AsciiString anEntry, aListRes("[");
2052 // Iterate over the sequence aSeq
2053 Standard_Integer aNbGroups = aSeq->Length();
2054 Standard_Integer i = 1;
2055 for (; i <= aNbGroups; i++) {
2056 Handle(Standard_Transient) anItem = aSeq->Value(i);
2057 if (anItem.IsNull()) continue;
2058 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2059 if (aGroup.IsNull()) continue;
2060 //Make a Python command
2061 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2062 aListRes += anEntry + ", ";
2064 aListRes.Trunc(aListRes.Length() - 2);
2066 GEOM::TPythonDump pd (aFunction);
2068 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2069 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2070 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2073 // thickness reduction
2075 pd << ", theRL=" << theRL << ", theWL=" << theWL
2076 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2078 pd << ", theRR=" << theRR << ", theWR=" << theWR
2079 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2081 pd << ", theRI=" << theRI << ", theWI=" << theWI
2082 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2091 //=============================================================================
2093 * MakePipeTShapeWithPosition
2094 * Create a T-shape object with specified caracteristics for the main and
2095 * the incident pipes (radius, width, half-length).
2096 * The extremities of the main pipe are located on junctions points P1 and P2.
2097 * The extremity of the incident pipe is located on junction point P3.
2098 * \param theR1 Internal radius of main pipe
2099 * \param theW1 Width of main pipe
2100 * \param theL1 Half-length of main pipe
2101 * \param theR2 Internal radius of incident pipe (R2 < R1)
2102 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2103 * \param theL2 Half-length of incident pipe
2104 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2105 * \param theP1 1st junction point of main pipe
2106 * \param theP2 2nd junction point of main pipe
2107 * \param theP3 Junction point of incident pipe
2108 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2110 //=============================================================================
2111 Handle(TColStd_HSequenceOfTransient)
2112 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2113 (double theR1, double theW1, double theL1,
2114 double theR2, double theW2, double theL2,
2115 double theRL, double theWL, double theLtransL, double theLthinL,
2116 double theRR, double theWR, double theLtransR, double theLthinR,
2117 double theRI, double theWI, double theLtransI, double theLthinI,
2119 Handle(GEOM_Object) theP1,
2120 Handle(GEOM_Object) theP2,
2121 Handle(GEOM_Object) theP3)
2125 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2129 //Add a new shape function with parameters
2130 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2131 if (aFunction.IsNull()) return NULL;
2133 //Check if the function is set correctly
2134 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2136 // Check new position
2137 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2141 AdvancedEngine_IPipeTShape aData(aFunction);
2149 aData.SetHexMesh(theHexMesh);
2151 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2152 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2153 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2155 //Compute the resulting value
2158 if (!GetSolver()->ComputeFunction(aFunction)) {
2159 SetErrorCode("TShape driver failed");
2164 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2166 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2170 if (isTRL || isTRR || isTRI) {
2171 // Add thickness reduction elements
2172 // at the three extremities: Left, Right and Incident
2173 TopoDS_Shape aResShape =
2174 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2175 theRL, theWL, theLtransL, theLthinL,
2176 theRR, theWR, theLtransR, theLthinR,
2177 theRI, theWI, theLtransI, theLthinI,
2179 aFunction->SetValue(aResShape);
2182 catch (Standard_Failure) {
2183 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2184 SetErrorCode(aFail->GetMessageString());
2188 TopoDS_Shape Te = aShape->GetValue();
2191 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2192 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2193 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2194 aFunction->SetValue(aTrsf_Shape);
2196 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2197 aSeq->Append(aShape);
2202 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2203 0., 0., 0., aSeq, aTrsf)) {
2208 // Get internal group.
2209 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2210 theRR, theLtransR, theRI, theLtransI,
2215 catch (Standard_Failure) {
2216 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2217 SetErrorCode(aFail->GetMessageString());
2221 //Make a Python command
2222 TCollection_AsciiString anEntry, aListRes("[");
2223 // Iterate over the sequence aSeq
2224 Standard_Integer aNbGroups = aSeq->Length();
2225 Standard_Integer i = 1;
2226 for (; i <= aNbGroups; i++) {
2227 Handle(Standard_Transient) anItem = aSeq->Value(i);
2228 if (anItem.IsNull()) continue;
2229 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2230 if (aGroup.IsNull()) continue;
2231 //Make a Python command
2232 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2233 aListRes += anEntry + ", ";
2235 aListRes.Trunc(aListRes.Length() - 2);
2237 GEOM::TPythonDump pd (aFunction);
2239 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2240 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2241 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2242 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2244 // thickness reduction
2246 pd << ", theRL=" << theRL << ", theWL=" << theWL
2247 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2249 pd << ", theRR=" << theRR << ", theWR=" << theWR
2250 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2252 pd << ", theRI=" << theRI << ", theWI=" << theWI
2253 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2262 //=============================================================================
2264 * MakePipeTShapeChamfer
2265 * Create a T-shape object with specified caracteristics for the main and
2266 * the incident pipes (radius, width, half-length). A chamfer is created
2267 * on the junction of the pipes.
2268 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2269 * \param theR1 Internal radius of main pipe
2270 * \param theW1 Width of main pipe
2271 * \param theL1 Half-length of main pipe
2272 * \param theR2 Internal radius of incident pipe (R2 < R1)
2273 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2274 * \param theL2 Half-length of incident pipe
2275 * \param theH Height of chamfer.
2276 * \param theW Width of chamfer.
2277 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2278 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2280 //=============================================================================
2281 Handle(TColStd_HSequenceOfTransient)
2282 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2283 (double theR1, double theW1, double theL1,
2284 double theR2, double theW2, double theL2,
2285 double theRL, double theWL, double theLtransL, double theLthinL,
2286 double theRR, double theWR, double theLtransR, double theLthinR,
2287 double theRI, double theWI, double theLtransI, double theLthinI,
2288 double theH, double theW,
2293 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2294 //Add a new shape function with parameters
2295 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2296 if (aFunction.IsNull()) return NULL;
2298 //Check if the function is set correctly
2299 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2301 AdvancedEngine_IPipeTShape aData(aFunction);
2311 aData.SetHexMesh(theHexMesh);
2313 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2314 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2315 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2317 //Compute the resulting value
2320 if (!GetSolver()->ComputeFunction(aFunction)) {
2321 SetErrorCode("TShape driver failed");
2325 catch (Standard_Failure) {
2326 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2327 SetErrorCode(aFail->GetMessageString());
2332 TopoDS_Shape aShapeShape = aShape->GetValue();
2333 TopTools_IndexedMapOfShape anEdgesIndices;
2334 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2335 // Common edges on external cylinders
2336 Handle(GEOM_Object) box_e;
2338 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2341 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2343 box_e->GetLastFunction()->SetDescription("");
2344 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2345 box_e->GetLastFunction()->SetDescription("");
2347 Handle(TColStd_HSequenceOfInteger) edges_e =
2348 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2349 box_e->GetLastFunction()->SetDescription("");
2351 if (edges_e.IsNull() || edges_e->Length() == 0) {
2352 SetErrorCode("External edges not found");
2355 int nbEdgesInChamfer = 0;
2356 std::list<int> theEdges;
2357 for (int i=1; i<=edges_e->Length();i++) {
2358 int edgeID = edges_e->Value(i);
2359 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2360 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2364 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2365 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2366 nbEdgesInChamfer ++;
2367 theEdges.push_back(edgeID);
2371 if (theHexMesh && nbEdgesInChamfer == 1)
2374 Handle(GEOM_Object) aChamfer;
2376 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2378 catch (Standard_Failure) {
2379 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2380 SetErrorCode(aFail->GetMessageString());
2383 if (aChamfer.IsNull()) {
2384 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2387 aChamfer->GetLastFunction()->SetDescription("");
2389 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2390 aFunction->SetValue(aChamferShape);
2394 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2396 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2400 // Add thickness reduction elements
2401 // at the three extremities: Left, Right and Incident
2404 if (isTRL || isTRR || isTRI) {
2405 TopoDS_Shape aResShape =
2406 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2407 theRL, theWL, theLtransL, theLthinL,
2408 theRR, theWR, theLtransR, theLthinR,
2409 theRI, theWI, theLtransI, theLthinI,
2411 aFunction->SetValue(aResShape);
2414 catch (Standard_Failure) {
2415 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2416 SetErrorCode(aFail->GetMessageString());
2420 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2421 aSeq->Append(aShape);
2426 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2427 theH, theW, 0., aSeq, gp_Trsf()))
2431 // Get internal group.
2432 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2433 theRR, theLtransR, theRI, theLtransI,
2438 catch (Standard_Failure) {
2439 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2440 SetErrorCode(aFail->GetMessageString());
2444 //Make a Python command
2445 TCollection_AsciiString anEntry, aListRes("[");
2446 // Iterate over the sequence aSeq
2447 Standard_Integer aNbGroups = aSeq->Length();
2448 Standard_Integer i = 1;
2449 for (; i <= aNbGroups; i++) {
2450 Handle(Standard_Transient) anItem = aSeq->Value(i);
2451 if (anItem.IsNull()) continue;
2452 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2453 if (aGroup.IsNull()) continue;
2454 //Make a Python command
2455 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2456 aListRes += anEntry + ", ";
2458 aListRes.Trunc(aListRes.Length() - 2);
2460 GEOM::TPythonDump pd (aFunction);
2462 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2463 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2464 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2465 << theH << ", " << theW << ", " << theHexMesh;
2467 // thickness reduction
2469 pd << ", theRL=" << theRL << ", theWL=" << theWL
2470 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2472 pd << ", theRR=" << theRR << ", theWR=" << theWR
2473 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2475 pd << ", theRI=" << theRI << ", theWI=" << theWI
2476 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2485 //=============================================================================
2487 * MakePipeTShapeChamferWithPosition
2488 * Create a T-shape object with specified caracteristics for the main and
2489 * the incident pipes (radius, width, half-length). A chamfer is created
2490 * on the junction of the pipes.
2491 * The extremities of the main pipe are located on junctions points P1 and P2.
2492 * The extremity of the incident pipe is located on junction point P3.
2493 * \param theR1 Internal radius of main pipe
2494 * \param theW1 Width of main pipe
2495 * \param theL1 Half-length of main pipe
2496 * \param theR2 Internal radius of incident pipe (R2 < R1)
2497 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2498 * \param theL2 Half-length of incident pipe
2499 * \param theH Height of chamfer.
2500 * \param theW Width of chamfer.
2501 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2502 * \param theP1 1st junction point of main pipe
2503 * \param theP2 2nd junction point of main pipe
2504 * \param theP3 Junction point of incident pipe
2505 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2507 //=============================================================================
2508 Handle(TColStd_HSequenceOfTransient)
2509 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2510 (double theR1, double theW1, double theL1,
2511 double theR2, double theW2, double theL2,
2512 double theRL, double theWL, double theLtransL, double theLthinL,
2513 double theRR, double theWR, double theLtransR, double theLthinR,
2514 double theRI, double theWI, double theLtransI, double theLthinI,
2515 double theH, double theW,
2517 Handle(GEOM_Object) theP1,
2518 Handle(GEOM_Object) theP2,
2519 Handle(GEOM_Object) theP3)
2523 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2524 //Add a new shape function with parameters
2525 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2526 if (aFunction.IsNull()) return NULL;
2528 //Check if the function is set correctly
2529 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2531 // Check new position
2532 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2536 AdvancedEngine_IPipeTShape aData(aFunction);
2546 aData.SetHexMesh(theHexMesh);
2548 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2549 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2550 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2552 //Compute the resulting value
2555 if (!GetSolver()->ComputeFunction(aFunction)) {
2556 SetErrorCode("TShape driver failed");
2560 catch (Standard_Failure) {
2561 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2562 SetErrorCode(aFail->GetMessageString());
2567 TopoDS_Shape aShapeShape = aShape->GetValue();
2568 TopTools_IndexedMapOfShape anEdgesIndices;
2569 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2570 // Common edges on external cylinders
2571 Handle(GEOM_Object) box_e;
2573 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2576 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2578 box_e->GetLastFunction()->SetDescription("");
2579 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2580 box_e->GetLastFunction()->SetDescription("");
2582 Handle(TColStd_HSequenceOfInteger) edges_e =
2583 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2584 box_e->GetLastFunction()->SetDescription("");
2586 if (edges_e.IsNull() || edges_e->Length() == 0) {
2587 SetErrorCode("External edges not found");
2590 int nbEdgesInChamfer = 0;
2591 std::list<int> theEdges;
2592 for (int i=1; i<=edges_e->Length();i++) {
2593 int edgeID = edges_e->Value(i);
2594 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2595 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2597 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2598 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2599 nbEdgesInChamfer ++;
2600 theEdges.push_back(edgeID);
2604 if (theHexMesh && nbEdgesInChamfer == 1)
2607 Handle(GEOM_Object) aChamfer;
2609 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2611 catch (Standard_Failure) {
2612 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2613 SetErrorCode(aFail->GetMessageString());
2616 if (aChamfer.IsNull()) {
2617 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2620 aChamfer->GetLastFunction()->SetDescription("");
2622 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2623 aFunction->SetValue(aChamferShape);
2627 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2629 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2633 // Add thickness reduction elements
2634 // at the three extremities: Left, Right and Incident
2637 if (isTRL || isTRR || isTRI) {
2638 TopoDS_Shape aResShape =
2639 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2640 theRL, theWL, theLtransL, theLthinL,
2641 theRR, theWR, theLtransR, theLthinR,
2642 theRI, theWI, theLtransI, theLthinI,
2644 aFunction->SetValue(aResShape);
2647 catch (Standard_Failure) {
2648 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2649 SetErrorCode(aFail->GetMessageString());
2654 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2655 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2656 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2657 aFunction->SetValue(aTrsf_Shape);
2659 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2660 aSeq->Append(aShape);
2665 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2666 theH, theW, 0., aSeq, aTrsf))
2670 // Get internal group.
2671 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2672 theRR, theLtransR, theRI, theLtransI,
2677 catch (Standard_Failure) {
2678 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2679 SetErrorCode(aFail->GetMessageString());
2683 //Make a Python command
2684 TCollection_AsciiString anEntry, aListRes("[");
2685 // Iterate over the sequence aSeq
2686 Standard_Integer aNbGroups = aSeq->Length();
2687 Standard_Integer i = 1;
2688 for (; i <= aNbGroups; i++) {
2689 Handle(Standard_Transient) anItem = aSeq->Value(i);
2690 if (anItem.IsNull()) continue;
2691 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2692 if (aGroup.IsNull()) continue;
2693 //Make a Python command
2694 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2695 aListRes += anEntry + ", ";
2697 aListRes.Trunc(aListRes.Length() - 2);
2699 GEOM::TPythonDump pd (aFunction);
2701 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2702 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2703 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2704 << theH << ", " << theW << ", " << theHexMesh << ", "
2705 << theP1 << ", " << theP2 << ", " << theP3;
2707 // thickness reduction
2709 pd << ", theRL=" << theRL << ", theWL=" << theWL
2710 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2712 pd << ", theRR=" << theRR << ", theWR=" << theWR
2713 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2715 pd << ", theRI=" << theRI << ", theWI=" << theWI
2716 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2725 //=============================================================================
2727 * MakePipeTShapeFillet
2728 * Create a T-shape object with specified caracteristics for the main and
2729 * the incident pipes (radius, width, half-length). A fillet is created
2730 * on the junction of the pipes.
2731 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2732 * \param theR1 Internal radius of main pipe
2733 * \param theW1 Width of main pipe
2734 * \param theL1 Half-length of main pipe
2735 * \param theR2 Internal radius of incident pipe (R2 < R1)
2736 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2737 * \param theL2 Half-length of incident pipe
2738 * \param theRF Radius of curvature of fillet.
2739 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2740 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2742 //=============================================================================
2743 Handle(TColStd_HSequenceOfTransient)
2744 AdvancedEngine_IOperations::MakePipeTShapeFillet
2745 (double theR1, double theW1, double theL1,
2746 double theR2, double theW2, double theL2,
2747 double theRL, double theWL, double theLtransL, double theLthinL,
2748 double theRR, double theWR, double theLtransR, double theLthinR,
2749 double theRI, double theWI, double theLtransI, double theLthinI,
2750 double theRF, bool theHexMesh)
2754 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2755 //Add a new shape function with parameters
2756 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2757 if (aFunction.IsNull()) return NULL;
2759 //Check if the function is set correctly
2760 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2762 AdvancedEngine_IPipeTShape aData(aFunction);
2771 aData.SetHexMesh(theHexMesh);
2773 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2774 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2775 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2777 //Compute the resulting value
2780 if (!GetSolver()->ComputeFunction(aFunction)) {
2781 SetErrorCode("TShape driver failed");
2785 catch (Standard_Failure) {
2786 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2787 SetErrorCode(aFail->GetMessageString());
2792 TopoDS_Shape aShapeShape = aShape->GetValue();
2793 TopTools_IndexedMapOfShape anEdgesIndices;
2794 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2795 // Common edges on external cylinders
2796 Handle(GEOM_Object) box_e;
2798 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2801 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2803 box_e->GetLastFunction()->SetDescription("");
2804 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2805 box_e->GetLastFunction()->SetDescription("");
2807 Handle(TColStd_HSequenceOfInteger) edges_e =
2808 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2809 box_e->GetLastFunction()->SetDescription("");
2811 if (edges_e.IsNull() || edges_e->Length() == 0) {
2812 SetErrorCode("External edges not found");
2815 int nbEdgesInFillet = 0;
2816 std::list<int> theEdges;
2817 for (int i=1; i<=edges_e->Length();i++) {
2818 int edgeID = edges_e->Value(i);
2819 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2820 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2822 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2823 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2825 theEdges.push_back(edgeID);
2829 if (theHexMesh && nbEdgesInFillet == 1)
2833 Handle(GEOM_Object) aFillet;
2835 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2837 catch (Standard_Failure) {
2838 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2839 SetErrorCode(aFail->GetMessageString());
2842 if (aFillet.IsNull()) {
2843 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2844 SetErrorCode(myLocalOperations->GetErrorCode());
2847 aFillet->GetLastFunction()->SetDescription("");
2849 TopoDS_Shape aFilletShape = aFillet->GetValue();
2851 #ifdef FILLET_FIX_TOLERANCE
2852 // VSR: 30/12/2014: temporary workaround about Fillet problem
2854 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2857 GEOMUtils::FixShapeCurves(aFilletShape);
2861 aFunction->SetValue(aFilletShape);
2864 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2865 // the following block, when enabled, leads to partitioning problems
2867 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2868 // BEGIN: Limit tolerances (debug)
2869 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2870 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2871 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2872 aCorr1->GetLastFunction()->SetDescription("");
2873 // END: Limit tolerances (debug)
2874 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2876 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2879 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2881 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2885 // Add thickness reduction elements
2886 // at the three extremities: Left, Right and Incident
2889 if (isTRL || isTRR || isTRI) {
2890 TopoDS_Shape aResShape =
2891 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2892 theRL, theWL, theLtransL, theLthinL,
2893 theRR, theWR, theLtransR, theLthinR,
2894 theRI, theWI, theLtransI, theLthinI,
2896 aFunction->SetValue(aResShape);
2899 catch (Standard_Failure) {
2900 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2901 SetErrorCode(aFail->GetMessageString());
2905 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2906 aSeq->Append(aShape);
2911 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2912 0., 0., theRF, aSeq, gp_Trsf()))
2916 // Get internal group.
2917 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2918 theRR, theLtransR, theRI, theLtransI,
2923 catch (Standard_Failure) {
2924 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2925 SetErrorCode(aFail->GetMessageString());
2929 //Make a Python command
2930 TCollection_AsciiString anEntry, aListRes("[");
2931 // Iterate over the sequence aSeq
2932 Standard_Integer aNbGroups = aSeq->Length();
2933 Standard_Integer i = 1;
2934 for (; i <= aNbGroups; i++) {
2935 Handle(Standard_Transient) anItem = aSeq->Value(i);
2936 if (anItem.IsNull()) continue;
2937 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2938 if (aGroup.IsNull()) continue;
2939 //Make a Python command
2940 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2941 aListRes += anEntry + ", ";
2943 aListRes.Trunc(aListRes.Length() - 2);
2945 GEOM::TPythonDump pd (aFunction);
2947 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2948 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2949 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2950 << theRF << ", " << theHexMesh;
2952 // thickness reduction
2954 pd << ", theRL=" << theRL << ", theWL=" << theWL
2955 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2957 pd << ", theRR=" << theRR << ", theWR=" << theWR
2958 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2960 pd << ", theRI=" << theRI << ", theWI=" << theWI
2961 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2970 //=============================================================================
2972 * MakePipeTShapeFilletWithPosition
2973 * \brief Create a T-shape object with specified caracteristics for the main and
2974 * the incident pipes (radius, width, half-length). A fillet is created
2975 * on the junction of the pipes.
2976 * The extremities of the main pipe are located on junctions points P1 and P2.
2977 * The extremity of the incident pipe is located on junction point P3.
2978 * \param theR1 Internal radius of main pipe
2979 * \param theW1 Width of main pipe
2980 * \param theL1 Half-length of main pipe
2981 * \param theR2 Internal radius of incident pipe (R2 < R1)
2982 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2983 * \param theL2 Half-length of incident pipe
2984 * \param theRF Radius of curvature of fillet
2985 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2986 * \param theP1 1st junction point of main pipe
2987 * \param theP2 2nd junction point of main pipe
2988 * \param theP3 Junction point of incident pipe
2989 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2991 //=============================================================================
2992 Handle(TColStd_HSequenceOfTransient)
2993 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2994 (double theR1, double theW1, double theL1,
2995 double theR2, double theW2, double theL2,
2996 double theRL, double theWL, double theLtransL, double theLthinL,
2997 double theRR, double theWR, double theLtransR, double theLthinR,
2998 double theRI, double theWI, double theLtransI, double theLthinI,
2999 double theRF, bool theHexMesh,
3000 Handle(GEOM_Object) theP1,
3001 Handle(GEOM_Object) theP2,
3002 Handle(GEOM_Object) theP3)
3006 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
3007 //Add a new shape function with parameters
3008 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
3009 if (aFunction.IsNull()) return NULL;
3011 //Check if the function is set correctly
3012 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
3014 // Check new position
3015 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3019 AdvancedEngine_IPipeTShape aData(aFunction);
3028 aData.SetHexMesh(theHexMesh);
3030 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3031 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3032 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3034 //Compute the resulting value
3037 if (!GetSolver()->ComputeFunction(aFunction)) {
3038 SetErrorCode("TShape driver failed");
3042 catch (Standard_Failure) {
3043 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3044 SetErrorCode(aFail->GetMessageString());
3049 TopoDS_Shape aShapeShape = aShape->GetValue();
3050 TopTools_IndexedMapOfShape anEdgesIndices;
3051 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3052 // Common edges on external cylinders
3053 Handle(GEOM_Object) box_e;
3055 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3058 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3060 box_e->GetLastFunction()->SetDescription("");
3061 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3062 box_e->GetLastFunction()->SetDescription("");
3064 Handle(TColStd_HSequenceOfInteger) edges_e =
3065 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3066 box_e->GetLastFunction()->SetDescription("");
3068 if (edges_e.IsNull() || edges_e->Length() == 0) {
3069 SetErrorCode("External edges not found");
3072 int nbEdgesInFillet = 0;
3073 std::list<int> theEdges;
3074 for (int i=1; i<=edges_e->Length();i++) {
3075 int edgeID = edges_e->Value(i);
3076 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3077 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3079 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3080 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3082 theEdges.push_back(edgeID);
3086 if (theHexMesh && nbEdgesInFillet == 1)
3090 Handle(GEOM_Object) aFillet;
3092 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3094 catch (Standard_Failure) {
3095 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3096 SetErrorCode(aFail->GetMessageString());
3099 if (aFillet.IsNull()) {
3100 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3103 aFillet->GetLastFunction()->SetDescription("");
3105 TopoDS_Shape aFilletShape = aFillet->GetValue();
3107 #ifdef FILLET_FIX_TOLERANCE
3108 // VSR: 30/12/2014: temporary workaround about Fillet problem
3110 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3113 GEOMUtils::FixShapeCurves(aFilletShape);
3117 aFunction->SetValue(aFilletShape);
3120 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3121 // the following block, when enabled, leads to partitioning problems
3123 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3124 // BEGIN: Limit tolerances (debug)
3125 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3126 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3127 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3128 aCorr1->GetLastFunction()->SetDescription("");
3129 // END: Limit tolerances (debug)
3130 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3132 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3135 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3137 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3141 // Add thickness reduction elements
3142 // at the three extremities: Left, Right and Incident
3145 if (isTRL || isTRR || isTRI) {
3146 TopoDS_Shape aResShape =
3147 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3148 theRL, theWL, theLtransL, theLthinL,
3149 theRR, theWR, theLtransR, theLthinR,
3150 theRI, theWI, theLtransI, theLthinI,
3152 aFunction->SetValue(aResShape);
3155 catch (Standard_Failure) {
3156 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3157 SetErrorCode(aFail->GetMessageString());
3162 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3163 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3164 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3165 aFunction->SetValue(aTrsf_Shape);
3167 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3168 aSeq->Append(aShape);
3173 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3174 0., 0., theRF, aSeq, aTrsf))
3178 // Get internal group.
3179 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3180 theRR, theLtransR, theRI, theLtransI,
3185 catch (Standard_Failure) {
3186 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3187 SetErrorCode(aFail->GetMessageString());
3191 //Make a Python command
3192 TCollection_AsciiString anEntry, aListRes("[");
3193 // Iterate over the sequence aSeq
3194 Standard_Integer aNbGroups = aSeq->Length();
3195 Standard_Integer i = 1;
3196 for (; i <= aNbGroups; i++) {
3197 Handle(Standard_Transient) anItem = aSeq->Value(i);
3198 if (anItem.IsNull()) continue;
3199 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3200 if (aGroup.IsNull()) continue;
3201 //Make a Python command
3202 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3203 aListRes += anEntry + ", ";
3205 aListRes.Trunc(aListRes.Length() - 2);
3207 GEOM::TPythonDump pd (aFunction);
3209 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3210 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3211 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3212 << theRF << ", " << theHexMesh << ", "
3213 << theP1 << ", " << theP2 << ", " << theP3;
3215 // thickness reduction
3217 pd << ", theRL=" << theRL << ", theWL=" << theWL
3218 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3220 pd << ", theRR=" << theRR << ", theWR=" << theWR
3221 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3223 pd << ", theRI=" << theRI << ", theWI=" << theWI
3224 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3233 //=============================================================================
3235 * This function allows to create a disk already divided into blocks. It can be
3236 * used to create divided pipes for later meshing in hexaedra.
3237 * \param theR Radius of the disk
3238 * \param theRatio Relative size of the central square diagonal against the disk diameter
3239 * \param theOrientation Plane on which the disk will be built
3240 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3241 * \return New GEOM_Object, containing the created shape.
3243 //=============================================================================
3244 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3245 int theOrientation, int thePattern)
3249 if (theOrientation != 1 &&
3250 theOrientation != 2 &&
3251 theOrientation != 3)
3253 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3257 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3259 //Add a new shape function with parameters
3260 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3261 if (aFunction.IsNull()) return NULL;
3263 //Check if the function is set correctly
3264 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3266 AdvancedEngine_IDividedDisk aData (aFunction);
3269 aData.SetRatio(theRatio);
3270 aData.SetOrientation(theOrientation);
3271 aData.SetType(thePattern);
3273 //Compute the resulting value
3276 if (!GetSolver()->ComputeFunction(aFunction)) {
3277 SetErrorCode("DividedDisk driver failed");
3281 catch (Standard_Failure) {
3282 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3283 SetErrorCode(aFail->GetMessageString());
3287 std::string aPatternStr;
3292 aPatternStr = "GEOM.SQUARE";
3295 aPatternStr = "GEOM.HEXAGON";
3299 //Make a Python command
3300 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3307 //=============================================================================
3309 * This function allows to create a disk already divided into blocks. It can be
3310 * used to create divided pipes for later meshing in hexaedra.
3311 * \param theR Radius of the disk
3312 * \param theRatio Relative size of the central square diagonal against the disk diameter
3313 * \return New GEOM_Object, containing the created shape.
3315 //=============================================================================
3316 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3317 Handle(GEOM_Object) theVec,
3325 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3327 //Add a new shape function with parameters
3328 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3329 if (aFunction.IsNull()) return NULL;
3331 //Check if the function is set correctly
3332 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3334 AdvancedEngine_IDividedDisk aData (aFunction);
3336 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3337 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3339 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3341 aData.SetCenter(aRefPnt);
3342 aData.SetVector(aRefVec);
3345 aData.SetRatio(theRatio);
3346 aData.SetType(thePattern);
3348 //Compute the resulting value
3351 if (!GetSolver()->ComputeFunction(aFunction)) {
3352 SetErrorCode("DividedDisk driver failed");
3356 catch (Standard_Failure) {
3357 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3358 SetErrorCode(aFail->GetMessageString());
3362 std::string aPatternStr;
3367 aPatternStr = "GEOM.SQUARE";
3370 aPatternStr = "GEOM.HEXAGON";
3375 //Make a Python command
3376 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3383 //=============================================================================
3385 * Builds a cylinder prepared for hexa meshes
3386 * \param theR Radius of the cylinder
3387 * \param theH Height of the cylinder
3388 * \return New GEOM_Object, containing the created shape.
3390 //=============================================================================
3391 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3398 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3400 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3401 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3403 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3405 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3406 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3407 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3409 std::string aPatternStr;
3414 aPatternStr = "GEOM.SQUARE";
3417 aPatternStr = "GEOM.HEXAGON";
3421 //Make a Python command
3422 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3428 //=============================================================================
3430 * Create a smoothing surface from a set of points
3431 * \param thelPoints list of points or compounds of points
3432 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3433 * \param theDegMax maximum degree of the resulting BSpline surface
3434 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3435 * \return New GEOM_Object, containing the created shape.
3437 //=============================================================================
3438 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3446 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3448 //Add a new shape function with parameters
3449 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3450 if (aFunction.IsNull()) return NULL;
3452 //Check if the function is set correctly
3453 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3455 AdvancedEngine_ISmoothingSurface aData (aFunction);
3457 int aLen = thelPoints.size();
3458 aData.SetLength(aLen);
3460 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3461 for (; it != thelPoints.end(); it++, ind++) {
3462 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3463 if (aRefObj.IsNull()) {
3464 SetErrorCode("NULL point or compound for bSplineFaceShape");
3467 aData.SetPntOrComp(ind, aRefObj);
3470 aData.SetNbMax(theNbMax);
3471 aData.SetDegMax(theDegMax);
3472 aData.SetDMax(theDMax);
3474 //Compute the resulting value
3477 if (!GetSolver()->ComputeFunction(aFunction)) {
3478 SetErrorCode("SmoothingSurface driver failed");
3482 catch (Standard_Failure) {
3483 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3484 SetErrorCode(aFail->GetMessageString());
3488 //Make a Python command
3489 GEOM::TPythonDump pd (aFunction);
3490 pd << aShape << " = geompy.MakeSmoothingSurface([";
3491 it = thelPoints.begin();
3493 while (it != thelPoints.end()) {
3494 pd << ", " << (*it++);
3498 << theDegMax << ", "