1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <utilities.h>
32 #include <Utils_ExceptHandlers.hxx>
34 #include <GEOM_Function.hxx>
35 #include <GEOM_PythonDump.hxx>
36 #include <GEOMUtils.hxx>
37 #include <GEOMAlgo_ClsfSurf.hxx>
38 #include <GEOMAlgo_FinderShapeOn2.hxx>
39 #include <GEOMAlgo_Splitter.hxx>
41 #include <GEOMImpl_Gen.hxx>
42 #include <GEOMImpl_Types.hxx>
44 #include <GEOMImpl_IBasicOperations.hxx>
45 #include <GEOMImpl_IBooleanOperations.hxx>
46 #include <GEOMImpl_IShapesOperations.hxx>
47 #include <GEOMImpl_ITransformOperations.hxx>
48 #include <GEOMImpl_IBlocksOperations.hxx>
49 #include <GEOMImpl_I3DPrimOperations.hxx>
50 #include <GEOMImpl_ILocalOperations.hxx>
51 #include <GEOMImpl_IHealingOperations.hxx>
52 #include <GEOMImpl_IGroupOperations.hxx>
53 #include <GEOMImpl_GlueDriver.hxx>
55 #include <TDF_Tool.hxx>
56 #include <TFunction_DriverTable.hxx>
57 #include <TFunction_Driver.hxx>
58 #include <TNaming_CopyShape.hxx>
61 #include <TopExp_Explorer.hxx>
63 #include <TopoDS_Vertex.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
65 #include <TopTools_ListIteratorOfListOfShape.hxx>
66 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
68 #include <BRep_Builder.hxx>
69 #include <BRep_Tool.hxx>
71 #include <BRepAdaptor_Surface.hxx>
72 #include <BRepAlgoAPI_Cut.hxx>
73 #include <BRepAlgoAPI_Fuse.hxx>
74 #include <BRepBuilderAPI_MakeFace.hxx>
75 #include <BRepBuilderAPI_MakeVertex.hxx>
76 #include <BRepBuilderAPI_Transform.hxx>
77 #include <BRepPrimAPI_MakeCone.hxx>
78 #include <BRepPrimAPI_MakeCylinder.hxx>
84 #include <GC_MakeConicalSurface.hxx>
85 #include <Geom_CylindricalSurface.hxx>
87 #include <ShapeAnalysis_Edge.hxx>
91 #include "AdvancedEngine_Types.hxx"
93 #include <Standard_Stream.hxx>
94 #include <Standard_Failure.hxx>
95 #include <StdFail_NotDone.hxx>
96 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
98 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
99 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
100 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
101 #define THICKNESS "Thickness" //"Epaisseur"
102 #define FLANGE "Flange" // "Collerette"
103 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
104 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
105 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
106 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
108 #define FIND_GROUPS_BY_POINTS 1
110 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
111 // VSR 30/12/2014: macro enabled
112 #define FILLET_FIX_TOLERANCE
114 //=============================================================================
118 //=============================================================================
119 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine) :
120 GEOM_IOperations(theEngine)
122 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
123 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine());
124 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine());
125 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine());
126 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine());
127 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine());
128 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine());
129 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine());
130 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine());
131 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine());
134 //=============================================================================
138 //=============================================================================
139 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
141 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
142 delete myBasicOperations;
143 delete myBooleanOperations;
144 delete myShapesOperations;
145 delete myTransformOperations;
146 delete myBlocksOperations;
147 delete my3DPrimOperations;
148 delete myLocalOperations;
149 delete myHealingOperations;
150 delete myGroupOperations;
153 //=============================================================================
157 //=============================================================================
158 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
159 Handle(GEOM_Object) theP1,
160 Handle(GEOM_Object) theP2,
161 Handle(GEOM_Object) theP3)
163 // Old Local Coordinates System oldLCS
165 gp_Pnt P1(-theL1, 0, 0);
166 gp_Pnt P2(theL1, 0, 0);
167 gp_Pnt P3(0, 0, theL2);
169 gp_Dir oldX(gp_Vec(P1, P2));
170 gp_Dir oldZ(gp_Vec(P0, P3));
171 gp_Ax3 oldLCS(P0, oldZ, oldX);
173 // New Local Coordinates System newLCS
174 double LocX, LocY, LocZ;
175 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
176 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
177 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
178 LocX = (newP1.X() + newP2.X()) / 2.;
179 LocY = (newP1.Y() + newP2.Y()) / 2.;
180 LocZ = (newP1.Z() + newP2.Z()) / 2.;
181 gp_Pnt newO(LocX, LocY, LocZ);
183 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
184 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
185 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
188 aTrsf.SetDisplacement(oldLCS, newLCS);
193 //=============================================================================
195 * CheckCompatiblePosition
198 //=============================================================================
199 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
200 Handle(GEOM_Object) theP1,
201 Handle(GEOM_Object) theP2,
202 Handle(GEOM_Object) theP3,
206 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
207 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
208 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
210 double d12 = P1.Distance(P2);
211 double d13 = P1.Distance(P3);
212 double d23 = P2.Distance(P3);
213 // double d2 = newO.Distance(P3);
215 if (Abs(d12) <= Precision::Confusion()) {
216 SetErrorCode("Junctions points P1 and P2 are identical");
219 if (Abs(d13) <= Precision::Confusion()) {
220 SetErrorCode("Junctions points P1 and P3 are identical");
223 if (Abs(d23) <= Precision::Confusion()) {
224 SetErrorCode("Junctions points P2 and P3 are identical");
229 double newL1 = 0.5 * d12;
230 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
232 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
234 if (fabs(newL1 - theL1) > Precision::Approximation()) {
235 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
236 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
237 // std::cerr << "theL1 = newL1" << std::endl;
241 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
247 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
249 if (fabs(newL2 - theL2) > Precision::Approximation()) {
250 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
251 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
255 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
265 //=============================================================================
267 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
269 //=============================================================================
270 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
271 double theR1, double theW1, double theL1,
272 double theR2, double theW2, double theL2,
273 double theH, double theW, double theRF,
274 Handle(TColStd_HSequenceOfTransient) theSeq,
279 if (theShape.IsNull()) return false;
281 TopoDS_Shape aShape = theShape->GetValue();
282 if (aShape.IsNull()) {
283 SetErrorCode("Shape is not defined");
287 // int expectedGroups = 0;
288 // if (shapeType == TSHAPE_BASIC)
289 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
290 // expectedGroups = 10;
292 // expectedGroups = 11;
293 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
294 // expectedGroups = 12;
296 double aR1Ext = theR1 + theW1;
297 double aR2Ext = theR2 + theW2;
299 /////////////////////////
300 //// Groups of Faces ////
301 /////////////////////////
304 // Comment the following lines when GetInPlace bug is solved
306 // Workaround of GetInPlace bug
307 // Create a bounding box that fits the shape
308 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
309 aBox->GetLastFunction()->SetDescription("");
310 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
311 aBox->GetLastFunction()->SetDescription("");
312 // Apply transformation to box
313 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
314 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
315 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
317 // Get the shell of the box
318 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
319 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
320 aBox->GetLastFunction()->SetDescription("");
321 aShell->GetLastFunction()->SetDescription("");
322 // Get the common shapes between shell and shape
323 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
324 (theShape, aShell, 1, Standard_False); // MakeCommon
325 if (aCommonCompound.IsNull()) {
326 SetErrorCode(myBooleanOperations->GetErrorCode());
329 aCommonCompound->GetLastFunction()->SetDescription("");
330 // Explode the faces of common shapes => 3 faces
331 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
332 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
333 aCommonCompound->GetLastFunction()->SetDescription("");
334 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
336 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
337 std::list<Handle(GEOM_Object)> aFacesList;
338 for (int j = 1 ; j <= 4 ; j++) {
339 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
340 if (!aFace.IsNull()) {
341 aFace->GetLastFunction()->SetDescription("");
342 aFacesList.push_back(aFace);
345 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
346 if (!aCompoundOfFaces.IsNull()) {
347 aCompoundOfFaces->GetLastFunction()->SetDescription("");
348 aCompoundOfFacesList.push_back(aCompoundOfFaces);
352 if (aCompoundOfFacesList.size() == 3) {
353 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
354 aCompoundOfFacesList.pop_front();
355 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
356 aCompoundOfFacesList.pop_front();
357 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
363 // Uncomment the following lines when GetInPlace bug is solved
365 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
366 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
367 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
368 // aP1->GetLastFunction()->SetDescription("");
369 // aP2->GetLastFunction()->SetDescription("");
370 // aP3->GetLastFunction()->SetDescription("");
371 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
372 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
373 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
374 // aV1->GetLastFunction()->SetDescription("");
375 // aV2->GetLastFunction()->SetDescription("");
376 // aV3->GetLastFunction()->SetDescription("");
377 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
378 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
379 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
380 // aPln1->GetLastFunction()->SetDescription("");
381 // aPln2->GetLastFunction()->SetDescription("");
382 // aPln3->GetLastFunction()->SetDescription("");
384 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
385 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
386 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
387 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
388 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
389 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
390 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
391 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
392 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
396 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
397 if (junctionFaces1.IsNull())
398 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
399 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
400 if (!junctionFaces1.IsNull()) {
401 junctionFaces1->GetLastFunction()->SetDescription("");
402 junctionFaces1->SetName("JUNCTION_FACE_1");
403 theSeq->Append(junctionFaces1);
406 SetErrorCode("Junction face 1 not found");
407 // theSeq->Append(aPln1);
410 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
411 if (junctionFaces2.IsNull())
412 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
413 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
414 if (!junctionFaces2.IsNull()) {
415 junctionFaces2->GetLastFunction()->SetDescription("");
416 junctionFaces2->SetName("JUNCTION_FACE_2");
417 theSeq->Append(junctionFaces2);
420 SetErrorCode("Junction face 2 not found");
421 // theSeq->Append(aPln2);
424 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
425 if (junctionFaces3.IsNull())
426 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
427 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
428 if (!junctionFaces3.IsNull()) {
429 junctionFaces3->GetLastFunction()->SetDescription("");
430 junctionFaces3->SetName("JUNCTION_FACE_3");
431 theSeq->Append(junctionFaces3);
434 SetErrorCode("Junction face 3 not found");
435 // theSeq->Append(aPln3);
438 // Comment the following lines when GetInPlace bug is solved
443 /////////////////////////
444 //// Groups of Edges ////
445 /////////////////////////
446 // Result of propagate
448 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
450 TCollection_AsciiString theDesc = aFunction->GetDescription();
451 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
452 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
453 SetErrorCode("Propagation groups not found");
456 Standard_Integer aNbGroups = aSeqPropagate->Length();
457 // Recover previous description to get rid of Propagate dump
458 aFunction->SetDescription(theDesc);
460 #ifdef FIND_GROUPS_BY_POINTS
461 // BEGIN: new groups search
470 .---.--'.. | | | ..'--.---.
471 |a \ '''...........''' / |
472 |-------\------' | '------/-------.
477 ._________________|_________________.
483 |-----------------|-----------------|
485 '-----------------'-----------------'
489 // "Thickness" group (a)
490 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
491 aPntA.Transform(aTrsf);
492 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
493 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
494 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
496 // "Circular quarter of pipe" group (b)
497 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
498 aPntB.Transform(aTrsf);
499 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
500 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
501 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
503 // "Circular quarter of pipe" group (c)
504 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
505 aPntC.Transform(aTrsf);
506 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
507 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
508 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
510 // "Main pipe half length" group (d)
511 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
512 aPntD.Transform(aTrsf);
513 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
514 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
515 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
517 // "Incident pipe half length" group (e)
518 double aTol10 = Precision::Confusion() * 10.;
519 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
520 aPntE.Transform(aTrsf);
521 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
522 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
523 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
525 // "Flange" group (f)
526 double aFx = - aR2Ext - aTol10;
527 if (shapeType == TSHAPE_CHAMFER)
529 else if (shapeType == TSHAPE_FILLET)
531 gp_Pnt aPntF (aFx, 0, aR1Ext);
532 aPntF.Transform(aTrsf);
533 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
534 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
535 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
537 // "Chamfer or Fillet" group (g)
538 TopoDS_Shape anEdgeG;
539 if (shapeType == TSHAPE_CHAMFER) {
540 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
541 aPntG.Transform(aTrsf);
542 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
543 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
544 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
546 else if (shapeType == TSHAPE_FILLET) {
547 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
548 aPntG.Transform(aTrsf);
549 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
550 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
551 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
554 for (int i = 1 ; i <= aNbGroups; i++) {
555 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
559 TopoDS_Shape aGroupShape = aGroup->GetValue();
560 TopTools_IndexedMapOfShape anEdgesMap;
561 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
563 if (anEdgesMap.Contains(anEdgeA)) { // a
564 aGroup->SetName("THICKNESS");
565 theSeq->Append(aGroup);
567 else if (anEdgesMap.Contains(anEdgeB)) { // b
568 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
569 theSeq->Append(aGroup);
571 else if (anEdgesMap.Contains(anEdgeC)) { // c
572 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
573 theSeq->Append(aGroup);
575 else if (anEdgesMap.Contains(anEdgeD)) { // d
576 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
577 theSeq->Append(aGroup);
579 else if (anEdgesMap.Contains(anEdgeE)) { // e
580 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
581 theSeq->Append(aGroup);
583 else if (anEdgesMap.Contains(anEdgeF)) { // f
584 aGroup->SetName("FLANGE");
585 theSeq->Append(aGroup);
587 else if (shapeType == TSHAPE_CHAMFER) { // g
588 if (anEdgesMap.Contains(anEdgeG)) {
589 aGroup->SetName("CHAMFER");
590 theSeq->Append(aGroup);
593 else if (shapeType == TSHAPE_FILLET) { // g
594 if (anEdgesMap.Contains(anEdgeG)) {
595 aGroup->SetName("FILLET");
596 theSeq->Append(aGroup);
602 // END: new groups search
605 bool circularFoundAndAdded = false;
606 bool circularFound10 = false;
607 bool incidentPipeFound = false;
608 bool mainPipeFound = false;
609 bool mainPipeFoundAndAdded = false;
610 bool radialFound =false;
611 bool flangeFound = false;
612 bool flangeFoundAndAdded = false;
613 bool chamferOrFilletFound = false;
615 for (int i = 1 ; i <= aNbGroups; i++) {
618 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
622 gp_Trsf aTrsfInv = aTrsf.Inverted();
623 TopoDS_Shape aGroupShape = aGroup->GetValue();
624 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
625 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
627 TopTools_IndexedMapOfShape anEdgesMap;
628 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
629 Standard_Integer nbEdges = anEdgesMap.Extent();
631 if (shapeType == TSHAPE_BASIC) {
632 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
634 aGroup->SetName("THICKNESS");
636 else if (nbEdges == 6) {
637 if (!circularFoundAndAdded) {
638 circularFoundAndAdded = true;
640 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
643 else if (nbEdges == 8) {
644 incidentPipeFound = true;
645 mainPipeFound = false;
649 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
651 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
652 double x=aP.X(), y=aP.Y(), z=aP.Z();
655 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
656 (Abs(y) > aR2Ext + Precision::Confusion())) {
657 incidentPipeFound = false;
660 if ( z < -Precision::Confusion()) {
661 // length of main pipe
662 mainPipeFound = true;
663 if (!mainPipeFoundAndAdded) {
664 mainPipeFoundAndAdded = true;
666 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
670 else if (Abs(x) > (theL1-Precision::Confusion())) {
671 // discretisation circulaire
673 if (!circularFoundAndAdded) {
674 circularFoundAndAdded = true;
676 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
681 if (incidentPipeFound) {
683 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
685 if (!addGroup && (!incidentPipeFound &&
689 // Flange (collerette)
692 aGroup->SetName("FLANGE");
698 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
699 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
701 aGroup->SetName("THICKNESS");
703 else if ((nbEdges == 10) || (nbEdges == 6)) {
704 if (!circularFoundAndAdded) {
706 circularFoundAndAdded = true;
707 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
709 circularFound10 = true;
712 else if (!circularFound10 && nbEdges == 10) {
713 circularFound10 = true;
715 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
718 else if (nbEdges == 8) {
719 incidentPipeFound = true;
720 mainPipeFound = true;
723 bool isNearZ0 = false;
724 bool isBelowZ0 = false;
726 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
728 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
729 double x=aP.X(), y=aP.Y(), z=aP.Z();
731 // tuy_princ_long_avant & tuy_princ_long_apres
732 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
733 // ((y <= aR1Ext + Precision::Confusion()) ||
734 // (y <= -(aR1Ext + Precision::Confusion())) ||
735 // (y <= theR1 + Precision::Confusion()) ||
736 // (y == -(theR1 + Precision::Confusion()))));
737 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
738 (fabs(y) > theR1 - Precision::Confusion() ||
739 fabs(y) < Precision::Confusion()));
742 mainPipeFound = false;
746 //if (z < Precision::Confusion() && !isMain) {
747 // flangeFound = true;
748 // if (!flangeFoundAndAdded) {
749 // flangeFoundAndAdded = true;
751 // aGroup->SetName("FLANGE");
754 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
755 if (z < - Precision::Confusion()) isBelowZ0 = true;
758 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
759 (Abs(y) > aR2Ext + Precision::Confusion())) {
760 incidentPipeFound = false;
766 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
768 if (incidentPipeFound) {
770 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
772 if (isNearZ0 && !isBelowZ0) {
774 if (!flangeFoundAndAdded) {
775 flangeFoundAndAdded = true;
777 aGroup->SetName("FLANGE");
780 if (!addGroup && (!incidentPipeFound &&
783 !chamferOrFilletFound)) {
785 chamferOrFilletFound = true;
786 if (shapeType == TSHAPE_CHAMFER)
787 aGroup->SetName("CHAMFER");
789 aGroup->SetName("FILLET");
795 // Add group to the list
797 theSeq->Append(aGroup);
805 //=============================================================================
807 * Return faces that are laying on surface.
809 //=============================================================================
810 bool AdvancedEngine_IOperations::GetFacesOnSurf
811 (const TopoDS_Shape &theShape,
812 const Handle(Geom_Surface)& theSurface,
813 const Standard_Real theTolerance,
814 TopTools_ListOfShape &theFaces)
816 GEOMAlgo_FinderShapeOn2 aFinder;
817 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
819 aClsfSurf->SetSurface(theSurface);
820 aFinder.SetShape(theShape);
821 aFinder.SetTolerance(theTolerance);
822 aFinder.SetClsf(aClsfSurf);
823 aFinder.SetShapeType(TopAbs_FACE);
824 aFinder.SetState(GEOMAlgo_ST_ON);
826 // Sets the minimal number of inner points for the faces that do not have own
827 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
829 aFinder.SetNbPntsMin(3);
830 // Sets the maximal number of inner points for edges or faces.
831 // It is useful for the cases when this number is very big (e.g =2000) to improve
832 // the performance. If this value =0, all inner points will be taken into account.
834 aFinder.SetNbPntsMax(100);
838 Standard_Integer iErr = aFinder.ErrorStatus();
839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
841 MESSAGE(" iErr : " << iErr);
842 TCollection_AsciiString aMsg (" iErr : ");
843 aMsg += TCollection_AsciiString(iErr);
847 Standard_Integer iWrn = aFinder.WarningStatus();
848 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
850 MESSAGE(" *** iWrn : " << iWrn);
853 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
854 TopTools_ListIteratorOfListOfShape anIter (aListRes);
856 for (; anIter.More(); anIter.Next()) {
857 theFaces.Append(anIter.Value());
863 //=============================================================================
865 * Creates and returns conical face.
867 //=============================================================================
868 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
869 (const gp_Ax2 &theAxis,
870 const double theRadius,
871 const double theRadiusThin,
872 const double theHeight,
873 const gp_Trsf &theTrsf)
875 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
876 TopoDS_Shape aResult;
879 if (aMkCone.IsDone()) {
880 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
882 for (; anExp.More(); anExp.Next()) {
883 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
885 if (aFace.IsNull() == Standard_False) {
886 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
888 if (anAdaptor.GetType() == GeomAbs_Cone) {
889 // This is a conical face. Transform and return it.
890 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
892 aResult = aTransf.Shape();
902 //=============================================================================
904 * Generate the internal group of a Pipe T-Shape
906 //=============================================================================
907 bool AdvancedEngine_IOperations::MakeInternalGroup
908 (const Handle(GEOM_Object) &theShape,
909 const double theR1, const double theLen1,
910 const double theR2, const double theLen2,
911 const double theRL, double theTransLenL,
912 const double theRR, double theTransLenR,
913 const double theRI, double theTransLenI,
914 const Handle(TColStd_HSequenceOfTransient) &theSeq,
915 const gp_Trsf &theTrsf)
919 if (theShape.IsNull()) {
923 TopoDS_Shape aShape = theShape->GetValue();
925 if (aShape.IsNull()) {
926 SetErrorCode("Shape is not defined");
931 Standard_Real aMaxTol = -RealLast();
932 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
934 for (; anExp.More(); anExp.Next()) {
935 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
937 if (aVertex.IsNull() == Standard_False) {
938 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
940 if (aTol > aMaxTol) {
946 // Construct internal surfaces.
947 Standard_Integer i = 0;
948 const Standard_Integer aMaxNbSurf = 5;
949 Handle(Geom_Surface) aSurface[aMaxNbSurf];
950 TopTools_ListOfShape aConicalFaces;
951 Standard_Real aTolConf = Precision::Confusion();
953 // 1. Construct the internal surface of main pipe.
954 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
955 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
957 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
959 // 2. Construct the internal surface of incident pipe.
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
962 // 3. Construct the internal surface of left reduction pipe.
963 if (theRL > aTolConf) {
964 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
966 if (theTransLenL > aTolConf) {
967 // 3.1. Construct the internal surface of left transition pipe.
968 gp_Pnt aPLeft (-theLen1, 0., 0.);
969 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
970 TopoDS_Shape aConeLeft =
971 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
973 if (aConeLeft.IsNull() == Standard_False) {
974 aConicalFaces.Append(aConeLeft);
979 // 4. Construct the internal surface of right reduction pipe.
980 if (theRR > aTolConf) {
981 // There is no need to construct another cylinder of the same radius. Skip it.
982 if (Abs(theRR - theRL) > aTolConf) {
983 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
986 if (theTransLenL > aTolConf) {
987 // 4.1. Construct the internal surface of right transition pipe.
988 gp_Pnt aPRight (theLen1, 0., 0.);
989 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
990 TopoDS_Shape aConeRight =
991 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
993 if (aConeRight.IsNull() == Standard_False) {
994 aConicalFaces.Append(aConeRight);
999 // 5. Construct the internal surface of incident reduction pipe.
1000 if (theRI > aTolConf) {
1001 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1003 if (theTransLenI > aTolConf) {
1004 // 5.1. Construct the internal surface of incident transition pipe.
1005 gp_Pnt aPInci (0., 0., theLen2);
1006 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1007 TopoDS_Shape aConeInci =
1008 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1010 if (aConeInci.IsNull() == Standard_False) {
1011 aConicalFaces.Append(aConeInci);
1016 // Get faces that are laying on cylindrical surfaces.
1017 TopTools_ListOfShape aFaces;
1018 gp_Trsf anInvTrsf = theTrsf.Inverted();
1020 for (i = 0; i < aMaxNbSurf; i++) {
1021 if (aSurface[i].IsNull()) {
1025 aSurface[i]->Transform(theTrsf);
1027 TopTools_ListOfShape aLocalFaces;
1029 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1034 // Check if the result contains outer cylinders.
1035 // It is required for main and incident pipes.
1036 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1038 while (anIter.More()) {
1039 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1040 Standard_Boolean isInside = Standard_False;
1042 // Get a vertex from this shape
1044 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1046 if (aVtx.IsNull() == Standard_False) {
1047 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1049 aPnt.Transform(anInvTrsf);
1052 // Check if the point is inside the main pipe.
1053 isInside = (Abs(aPnt.X()) <= theLen1);
1055 // Check if the point is inside the incident pipe.
1056 isInside = (aPnt.Z() <= theLen2);
1065 // Remove this face.
1066 aLocalFaces.Remove(anIter);
1071 aFaces.Append(aLocalFaces);
1074 // Get faces that are laying on conical faces.
1075 if (aConicalFaces.IsEmpty() == Standard_False) {
1076 Handle(GEOM_Object) aCone =
1077 GetEngine()->AddObject(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;
1342 int PZX=0, PZY=0; // todo: PZX, PZY must be explicitly initialized to avoid warning (see below)
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)); // todo: PZX must be explicitly initialized to avoid warning (see above)
1417 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1418 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4)); // todo: PZY must be explicitly initialized to avoid warning (see above)
1420 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1421 if (Cote_1.IsNull()) {
1422 SetErrorCode("Impossible to build edge in thickness");
1425 Cote_1->GetLastFunction()->SetDescription("");
1427 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1428 if (Cote_2.IsNull()) {
1429 SetErrorCode("Impossible to build edge in thickness");
1432 Cote_2->GetLastFunction()->SetDescription("");
1434 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1435 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1436 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1437 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1438 if (edge_chan_princ.IsNull()) {
1439 SetErrorCode("Impossible to find edge on main pipe");
1442 edge_chan_princ->GetLastFunction()->SetDescription("");
1444 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1445 if (edge_chan_inc.IsNull()) {
1446 SetErrorCode("Impossible to find edge on incident pipe");
1449 edge_chan_inc->GetLastFunction()->SetDescription("");
1451 std::list<Handle(GEOM_Object)> edgeList1;
1452 edgeList1.push_back(edge_chan_princ);
1453 edgeList1.push_back(Cote_1);
1454 edgeList1.push_back(arete_intersect_int);
1455 edgeList1.push_back(Cote_2);
1457 // std::cerr << "Creating wire 1" << std::endl;
1458 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1459 if (wire_t.IsNull()) {
1460 SetErrorCode("Impossible to build wire");
1463 wire_t->GetLastFunction()->SetDescription("");
1465 // std::cerr << "Creating face 1" << std::endl;
1466 face_t = myShapesOperations->MakeFace(wire_t, false);
1467 if (face_t.IsNull()) {
1468 SetErrorCode("Impossible to build face");
1471 face_t->GetLastFunction()->SetDescription("");
1472 theShapes.push_back(face_t);
1474 // Create a prism from edge_chan_inc
1475 Handle(GEOM_Object) aPrismDir = myBasicOperations->MakeVectorDXDYDZ(1., 1., 0.);
1477 if (aPrismDir.IsNull()) {
1478 SetErrorCode("Impossible to build Prism direction");
1481 aPrismDir->GetLastFunction()->SetDescription("");
1482 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, aPrismDir, theR2 + theW2);
1484 if (face_t2.IsNull()) {
1485 SetErrorCode("Impossible to build face");
1488 face_t2->GetLastFunction()->SetDescription("");
1489 theShapes.push_back(face_t2);
1493 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1494 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1495 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1496 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1497 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1498 aP0->GetLastFunction()->SetDescription("");
1499 aVZ->GetLastFunction()->SetDescription("");
1500 aVXZ->GetLastFunction()->SetDescription("");
1501 aPlnOZ->GetLastFunction()->SetDescription("");
1502 aPlnOXZ->GetLastFunction()->SetDescription("");
1503 theShapes.push_back(aPlnOZ);
1504 theShapes.push_back(aPlnOXZ);
1507 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1508 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1509 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1510 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1511 Handle(TColStd_HArray1OfInteger) theMaterials;
1513 partitionShapes->Append(theShape);
1514 theTools->Append(aPlnOZ);
1515 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1516 theTools->Append(aPlnOXZ);
1517 theTools->Append(face_t);
1519 theTools->Append(face_t2);
1521 Te3 = myBooleanOperations->MakePartition
1522 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1523 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1525 SetErrorCode("Impossible to build partition of TShape");
1528 Te3->GetLastFunction()->SetDescription("");
1530 // Last verification: result should be a block
1531 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1532 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1533 SetErrorCode("TShape is not a compound of block");
1537 // // BEGIN Compound of created shapes - Only for debug purpose
1538 // theShapes.clear();
1539 // theShapes.push_back(theShape);
1540 // theShapes.push_back(aPlnOZ);
1541 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1542 // theShapes.push_back(aPlnOXZ);
1543 // theShapes.push_back(face_t);
1545 // theShapes.push_back(face_t2);
1547 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1548 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1549 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1550 // // END Compound of created shapes - Only for debug purpose
1552 TopoDS_Shape aShape = Te3->GetValue();
1553 theShape->GetLastFunction()->SetValue(aShape);
1555 catch (Standard_Failure& aFail) {
1556 SetErrorCode(aFail.GetMessageString());
1564 // Mirror and glue faces
1565 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1566 double theR1, double theW1, double theL1,
1567 double /*theR2*/, double /*theW2*/, double theL2)
1572 double aSize = 2*(theL1 + theL2);
1573 double aR1Ext = theR1 + theW1;
1576 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1577 aP0->GetLastFunction()->SetDescription("");
1578 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1579 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1580 aVX->GetLastFunction()->SetDescription("");
1581 aVY->GetLastFunction()->SetDescription("");
1582 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1583 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1584 aPlane_OX->GetLastFunction()->SetDescription("");
1585 aPlane_OY->GetLastFunction()->SetDescription("");
1587 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1589 SetErrorCode("Impossible to build mirror of quarter TShape");
1593 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1595 SetErrorCode("Impossible to build mirror of half TShape");
1599 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1601 SetErrorCode("Impossible to build mirror of half TShape");
1605 std::list<Handle(GEOM_Object)> aShapesList;
1606 aShapesList.push_back(theShape);
1607 aShapesList.push_back(Te4);
1608 aShapesList.push_back(Te5);
1609 aShapesList.push_back(Te6);
1610 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1612 SetErrorCode("Impossible to build compound");
1616 // Copy source shape
1617 TopoDS_Shape aShapeCopy;
1618 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1619 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1621 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1622 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1624 SetErrorCode("Impossible to glue faces of TShape");
1628 TopoDS_Shape aShape = Te8->GetValue();
1629 BRepCheck_Analyzer anAna (aShape, Standard_True);
1631 if (!anAna.IsValid()) {
1632 // Try to do gluing with the tolerance equal to maximal
1633 // tolerance of vertices of the source shape.
1634 Standard_Real aTolMax = -RealLast();
1636 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1637 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1638 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1640 if (aTol > aTolMax) {
1646 Te7->GetLastFunction()->SetValue(aShapeCopy);
1647 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1650 SetErrorCode("Impossible to glue faces of TShape");
1654 aShape = Te8->GetValue();
1658 theShape->GetLastFunction()->SetValue(aShape);
1660 Te4->GetLastFunction()->SetDescription("");
1661 Te5->GetLastFunction()->SetDescription("");
1662 Te6->GetLastFunction()->SetDescription("");
1663 Te7->GetLastFunction()->SetDescription("");
1664 Te8->GetLastFunction()->SetDescription("");
1670 //=======================================================================
1671 //function : MakePipeTShapeThicknessReduction
1672 //purpose : Static method. Add thiskness reduction elements at the three
1673 // open ends of the T-Shape.
1674 //=======================================================================
1675 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1676 (TopoDS_Shape theShape,
1677 double r1, double w1, double l1,
1678 double r2, double w2, double l2,
1679 double rL, double wL, double ltransL, double lthinL,
1680 double rR, double wR, double ltransR, double lthinR,
1681 double rI, double wI, double ltransI, double lthinI,
1682 bool fuseReductions)
1684 // Add thickness reduction elements
1685 // at the three extremities: Left, Right and Incident
1687 ---------------------.
1689 ---------------------. \
1690 ^ \ '-----------------.
1692 | '-----------------'
1694 --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1698 TopoDS_Shape aResult = theShape;
1699 double aTol = Precision::Confusion();
1701 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1703 // Left reduction (rL, wL, ltransL, lthinL)
1704 if (rL > aTol && wL > aTol && ltransL > aTol) {
1705 gp_Pnt aPLeft (-l1, 0, 0);
1706 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1707 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1708 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1710 if (fuseReductions) {
1711 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1712 if (!fuseL.IsDone())
1713 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1714 aResult = fuseL.Shape();
1721 B.Add(C, aReductionLeft);
1727 if (rR > aTol && wR > aTol && ltransR > aTol) {
1728 gp_Pnt aPRight (l1, 0, 0);
1729 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1730 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1731 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1733 if (fuseReductions) {
1734 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1735 if (!fuseR.IsDone())
1736 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1737 aResult = fuseR.Shape();
1744 B.Add(C, aReductionRight);
1749 // Incident reduction
1750 if (rI > aTol && wI > aTol && ltransI > aTol) {
1751 gp_Pnt aPInci (0, 0, l2);
1752 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1753 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1754 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1756 if (fuseReductions) {
1757 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1758 if (!fuseInci.IsDone())
1759 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1760 aResult = fuseInci.Shape();
1767 B.Add(C, aReductionInci);
1772 // Get rid of extra compounds
1773 TopTools_ListOfShape listShapeRes;
1774 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1775 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1777 if (!fuseReductions && listShapeRes.Extent() > 1) {
1778 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1783 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1784 for (; itSub.More(); itSub.Next())
1785 B.Add(C, itSub.Value());
1788 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1794 //=======================================================================
1795 //function : MakeThicknessReduction
1796 //purpose : Static method. Create one thickness reduction element.
1797 //=======================================================================
1798 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1799 const double R, const double W,
1800 const double Rthin, const double Wthin,
1801 const double Ltrans, const double Lthin,
1804 double aTol = Precision::Confusion();
1805 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1806 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1808 bool isThinPart = (Lthin > aTol);
1814 ^ \ '-----------------.
1816 | '-----------------'
1818 --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1822 double RExt = R + W;
1823 double RthinExt = Rthin + Wthin;
1825 gp_Dir aNormal = theAxes.Direction();
1826 gp_Dir anXDir = theAxes.XDirection();
1827 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1828 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1830 // Build the transition part
1831 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1832 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1835 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1836 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1837 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1839 StdFail_NotDone::Raise("Couldn't build transition part of thickness reduction");
1840 TopoDS_Shape aReduction = cut1.Shape();
1842 // Build the thin part, if required
1843 TopoDS_Shape aThinPart;
1845 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1846 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1849 if (!CExt.IsDone() || !CInt.IsDone())
1850 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1851 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1853 StdFail_NotDone::Raise("Couldn't build thin part of thickness reduction");
1854 aThinPart = cut2.Shape();
1860 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1861 if (!fuse1.IsDone())
1862 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1863 aReduction = fuse1.Shape();
1867 // Partition the reduction on blocks
1868 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1869 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1870 gp_Pln aPln1 (anAxesPln1);
1871 gp_Pln aPln2 (anAxesPln2);
1872 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1873 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1874 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1876 GEOMAlgo_Splitter PS;
1877 PS.AddArgument(aReduction);
1879 PS.AddArgument(aThinPart);
1882 PS.SetLimit(TopAbs_SOLID);
1885 aReduction = PS.Shape();
1891 //=============================================================================
1894 * \brief Create a T-shape object with specified caracteristics for the main and
1895 * the incident pipes (radius, width, half-length).
1896 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1897 * \param theR1 Internal radius of main pipe
1898 * \param theW1 Width of main pipe
1899 * \param theL1 Half-length of main pipe
1900 * \param theR2 Internal radius of incident pipe (R2 < R1)
1901 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1902 * \param theL2 Half-length of incident pipe
1903 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1904 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1906 //=============================================================================
1907 Handle(TColStd_HSequenceOfTransient)
1908 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1909 double theR2, double theW2, double theL2,
1910 double theRL, double theWL, double theLtransL, double theLthinL,
1911 double theRR, double theWR, double theLtransR, double theLthinR,
1912 double theRI, double theWI, double theLtransI, double theLthinI,
1915 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1918 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
1920 //Add a new shape function with parameters
1921 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1922 if (aFunction.IsNull()) return NULL;
1924 //Check if the function is set correctly
1925 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1927 AdvancedEngine_IPipeTShape aData (aFunction);
1935 aData.SetHexMesh(theHexMesh);
1937 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1938 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1939 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1941 //Compute the resulting value
1944 if (!GetSolver()->ComputeFunction(aFunction)) {
1945 SetErrorCode("TShape driver failed");
1950 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1952 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1956 if (isTRL || isTRR || isTRI) {
1957 // Add thickness reduction elements
1958 // at the three extremities: Left, Right and Incident
1959 TopoDS_Shape aResShape =
1960 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1961 theRL, theWL, theLtransL, theLthinL,
1962 theRR, theWR, theLtransR, theLthinR,
1963 theRI, theWI, theLtransI, theLthinI,
1965 aFunction->SetValue(aResShape);
1968 catch (Standard_Failure& aFail) {
1969 SetErrorCode(aFail.GetMessageString());
1973 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1974 aSeq->Append(aShape);
1979 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1980 0., 0., 0., aSeq, gp_Trsf()))
1984 // Get internal group.
1985 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
1986 theRR, theLtransR, theRI, theLtransI,
1991 catch (Standard_Failure& aFail) {
1992 SetErrorCode(aFail.GetMessageString());
1996 //Make a Python command
1997 TCollection_AsciiString anEntry, aListRes("[");
1998 // Iterate over the sequence aSeq
1999 Standard_Integer aNbGroups = aSeq->Length();
2000 Standard_Integer i = 1;
2001 for (; i <= aNbGroups; i++) {
2002 Handle(Standard_Transient) anItem = aSeq->Value(i);
2003 if (anItem.IsNull()) continue;
2004 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2005 if (aGroup.IsNull()) continue;
2006 //Make a Python command
2007 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2008 aListRes += anEntry + ", ";
2010 aListRes.Trunc(aListRes.Length() - 2);
2012 GEOM::TPythonDump pd (aFunction);
2014 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2015 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2016 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2019 // thickness reduction
2021 pd << ", theRL=" << theRL << ", theWL=" << theWL
2022 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2024 pd << ", theRR=" << theRR << ", theWR=" << theWR
2025 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2027 pd << ", theRI=" << theRI << ", theWI=" << theWI
2028 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2037 //=============================================================================
2039 * MakePipeTShapeWithPosition
2040 * Create a T-shape object with specified caracteristics for the main and
2041 * the incident pipes (radius, width, half-length).
2042 * The extremities of the main pipe are located on junctions points P1 and P2.
2043 * The extremity of the incident pipe is located on junction point P3.
2044 * \param theR1 Internal radius of main pipe
2045 * \param theW1 Width of main pipe
2046 * \param theL1 Half-length of main pipe
2047 * \param theR2 Internal radius of incident pipe (R2 < R1)
2048 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2049 * \param theL2 Half-length of incident pipe
2050 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2051 * \param theP1 1st junction point of main pipe
2052 * \param theP2 2nd junction point of main pipe
2053 * \param theP3 Junction point of incident pipe
2054 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2056 //=============================================================================
2057 Handle(TColStd_HSequenceOfTransient)
2058 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2059 (double theR1, double theW1, double theL1,
2060 double theR2, double theW2, double theL2,
2061 double theRL, double theWL, double theLtransL, double theLthinL,
2062 double theRR, double theWR, double theLtransR, double theLthinR,
2063 double theRI, double theWI, double theLtransI, double theLthinI,
2065 Handle(GEOM_Object) theP1,
2066 Handle(GEOM_Object) theP2,
2067 Handle(GEOM_Object) theP3)
2071 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2075 //Add a new shape function with parameters
2076 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2077 if (aFunction.IsNull()) return NULL;
2079 //Check if the function is set correctly
2080 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2082 // Check new position
2083 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2087 AdvancedEngine_IPipeTShape aData(aFunction);
2095 aData.SetHexMesh(theHexMesh);
2097 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2098 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2099 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2101 //Compute the resulting value
2104 if (!GetSolver()->ComputeFunction(aFunction)) {
2105 SetErrorCode("TShape driver failed");
2110 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2112 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2116 if (isTRL || isTRR || isTRI) {
2117 // Add thickness reduction elements
2118 // at the three extremities: Left, Right and Incident
2119 TopoDS_Shape aResShape =
2120 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2121 theRL, theWL, theLtransL, theLthinL,
2122 theRR, theWR, theLtransR, theLthinR,
2123 theRI, theWI, theLtransI, theLthinI,
2125 aFunction->SetValue(aResShape);
2128 catch (Standard_Failure& aFail) {
2129 SetErrorCode(aFail.GetMessageString());
2133 TopoDS_Shape Te = aShape->GetValue();
2136 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2137 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2138 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2139 aFunction->SetValue(aTrsf_Shape);
2141 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2142 aSeq->Append(aShape);
2147 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2148 0., 0., 0., aSeq, aTrsf)) {
2153 // Get internal group.
2154 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2155 theRR, theLtransR, theRI, theLtransI,
2160 catch (Standard_Failure& aFail) {
2161 SetErrorCode(aFail.GetMessageString());
2165 //Make a Python command
2166 TCollection_AsciiString anEntry, aListRes("[");
2167 // Iterate over the sequence aSeq
2168 Standard_Integer aNbGroups = aSeq->Length();
2169 Standard_Integer i = 1;
2170 for (; i <= aNbGroups; i++) {
2171 Handle(Standard_Transient) anItem = aSeq->Value(i);
2172 if (anItem.IsNull()) continue;
2173 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2174 if (aGroup.IsNull()) continue;
2175 //Make a Python command
2176 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2177 aListRes += anEntry + ", ";
2179 aListRes.Trunc(aListRes.Length() - 2);
2181 GEOM::TPythonDump pd (aFunction);
2183 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2184 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2185 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2186 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2188 // thickness reduction
2190 pd << ", theRL=" << theRL << ", theWL=" << theWL
2191 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2193 pd << ", theRR=" << theRR << ", theWR=" << theWR
2194 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2196 pd << ", theRI=" << theRI << ", theWI=" << theWI
2197 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2206 //=============================================================================
2208 * MakePipeTShapeChamfer
2209 * Create a T-shape object with specified caracteristics for the main and
2210 * the incident pipes (radius, width, half-length). A chamfer is created
2211 * on the junction of the pipes.
2212 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2213 * \param theR1 Internal radius of main pipe
2214 * \param theW1 Width of main pipe
2215 * \param theL1 Half-length of main pipe
2216 * \param theR2 Internal radius of incident pipe (R2 < R1)
2217 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2218 * \param theL2 Half-length of incident pipe
2219 * \param theH Height of chamfer.
2220 * \param theW Width of chamfer.
2221 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2222 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2224 //=============================================================================
2225 Handle(TColStd_HSequenceOfTransient)
2226 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2227 (double theR1, double theW1, double theL1,
2228 double theR2, double theW2, double theL2,
2229 double theRL, double theWL, double theLtransL, double theLthinL,
2230 double theRR, double theWR, double theLtransR, double theLthinR,
2231 double theRI, double theWI, double theLtransI, double theLthinI,
2232 double theH, double theW,
2237 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2238 //Add a new shape function with parameters
2239 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2240 if (aFunction.IsNull()) return NULL;
2242 //Check if the function is set correctly
2243 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2245 AdvancedEngine_IPipeTShape aData(aFunction);
2255 aData.SetHexMesh(theHexMesh);
2257 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2258 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2259 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2261 //Compute the resulting value
2264 if (!GetSolver()->ComputeFunction(aFunction)) {
2265 SetErrorCode("TShape driver failed");
2269 catch (Standard_Failure& aFail) {
2270 SetErrorCode(aFail.GetMessageString());
2275 TopoDS_Shape aShapeShape = aShape->GetValue();
2276 TopTools_IndexedMapOfShape anEdgesIndices;
2277 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2278 // Common edges on external cylinders
2279 Handle(GEOM_Object) box_e;
2281 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2284 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2286 box_e->GetLastFunction()->SetDescription("");
2287 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2288 box_e->GetLastFunction()->SetDescription("");
2290 Handle(TColStd_HSequenceOfInteger) edges_e =
2291 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2292 box_e->GetLastFunction()->SetDescription("");
2294 if (edges_e.IsNull() || edges_e->Length() == 0) {
2295 SetErrorCode("External edges not found");
2298 int nbEdgesInChamfer = 0;
2299 std::list<int> theEdges;
2300 for (int i=1; i<=edges_e->Length();i++) {
2301 int edgeID = edges_e->Value(i);
2302 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2303 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2307 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2308 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2309 nbEdgesInChamfer ++;
2310 theEdges.push_back(edgeID);
2314 if (theHexMesh && nbEdgesInChamfer == 1)
2317 Handle(GEOM_Object) aChamfer;
2319 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2321 catch (Standard_Failure& aFail) {
2322 SetErrorCode(aFail.GetMessageString());
2325 if (aChamfer.IsNull()) {
2326 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2329 aChamfer->GetLastFunction()->SetDescription("");
2331 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2332 aFunction->SetValue(aChamferShape);
2336 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2338 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2342 // Add thickness reduction elements
2343 // at the three extremities: Left, Right and Incident
2346 if (isTRL || isTRR || isTRI) {
2347 TopoDS_Shape aResShape =
2348 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2349 theRL, theWL, theLtransL, theLthinL,
2350 theRR, theWR, theLtransR, theLthinR,
2351 theRI, theWI, theLtransI, theLthinI,
2353 aFunction->SetValue(aResShape);
2356 catch (Standard_Failure& aFail) {
2357 SetErrorCode(aFail.GetMessageString());
2361 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2362 aSeq->Append(aShape);
2367 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2368 theH, theW, 0., aSeq, gp_Trsf()))
2372 // Get internal group.
2373 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2374 theRR, theLtransR, theRI, theLtransI,
2379 catch (Standard_Failure& aFail) {
2380 SetErrorCode(aFail.GetMessageString());
2384 //Make a Python command
2385 TCollection_AsciiString anEntry, aListRes("[");
2386 // Iterate over the sequence aSeq
2387 Standard_Integer aNbGroups = aSeq->Length();
2388 Standard_Integer i = 1;
2389 for (; i <= aNbGroups; i++) {
2390 Handle(Standard_Transient) anItem = aSeq->Value(i);
2391 if (anItem.IsNull()) continue;
2392 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2393 if (aGroup.IsNull()) continue;
2394 //Make a Python command
2395 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2396 aListRes += anEntry + ", ";
2398 aListRes.Trunc(aListRes.Length() - 2);
2400 GEOM::TPythonDump pd (aFunction);
2402 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2403 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2404 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2405 << theH << ", " << theW << ", " << theHexMesh;
2407 // thickness reduction
2409 pd << ", theRL=" << theRL << ", theWL=" << theWL
2410 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2412 pd << ", theRR=" << theRR << ", theWR=" << theWR
2413 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2415 pd << ", theRI=" << theRI << ", theWI=" << theWI
2416 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2425 //=============================================================================
2427 * MakePipeTShapeChamferWithPosition
2428 * Create a T-shape object with specified caracteristics for the main and
2429 * the incident pipes (radius, width, half-length). A chamfer is created
2430 * on the junction of the pipes.
2431 * The extremities of the main pipe are located on junctions points P1 and P2.
2432 * The extremity of the incident pipe is located on junction point P3.
2433 * \param theR1 Internal radius of main pipe
2434 * \param theW1 Width of main pipe
2435 * \param theL1 Half-length of main pipe
2436 * \param theR2 Internal radius of incident pipe (R2 < R1)
2437 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2438 * \param theL2 Half-length of incident pipe
2439 * \param theH Height of chamfer.
2440 * \param theW Width of chamfer.
2441 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2442 * \param theP1 1st junction point of main pipe
2443 * \param theP2 2nd junction point of main pipe
2444 * \param theP3 Junction point of incident pipe
2445 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2447 //=============================================================================
2448 Handle(TColStd_HSequenceOfTransient)
2449 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2450 (double theR1, double theW1, double theL1,
2451 double theR2, double theW2, double theL2,
2452 double theRL, double theWL, double theLtransL, double theLthinL,
2453 double theRR, double theWR, double theLtransR, double theLthinR,
2454 double theRI, double theWI, double theLtransI, double theLthinI,
2455 double theH, double theW,
2457 Handle(GEOM_Object) theP1,
2458 Handle(GEOM_Object) theP2,
2459 Handle(GEOM_Object) theP3)
2463 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2464 //Add a new shape function with parameters
2465 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2466 if (aFunction.IsNull()) return NULL;
2468 //Check if the function is set correctly
2469 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2471 // Check new position
2472 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2476 AdvancedEngine_IPipeTShape aData(aFunction);
2486 aData.SetHexMesh(theHexMesh);
2488 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2489 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2490 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2492 //Compute the resulting value
2495 if (!GetSolver()->ComputeFunction(aFunction)) {
2496 SetErrorCode("TShape driver failed");
2500 catch (Standard_Failure& aFail) {
2501 SetErrorCode(aFail.GetMessageString());
2506 TopoDS_Shape aShapeShape = aShape->GetValue();
2507 TopTools_IndexedMapOfShape anEdgesIndices;
2508 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2509 // Common edges on external cylinders
2510 Handle(GEOM_Object) box_e;
2512 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2515 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2517 box_e->GetLastFunction()->SetDescription("");
2518 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2519 box_e->GetLastFunction()->SetDescription("");
2521 Handle(TColStd_HSequenceOfInteger) edges_e =
2522 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2523 box_e->GetLastFunction()->SetDescription("");
2525 if (edges_e.IsNull() || edges_e->Length() == 0) {
2526 SetErrorCode("External edges not found");
2529 int nbEdgesInChamfer = 0;
2530 std::list<int> theEdges;
2531 for (int i=1; i<=edges_e->Length();i++) {
2532 int edgeID = edges_e->Value(i);
2533 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2534 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2536 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2537 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2538 nbEdgesInChamfer ++;
2539 theEdges.push_back(edgeID);
2543 if (theHexMesh && nbEdgesInChamfer == 1)
2546 Handle(GEOM_Object) aChamfer;
2548 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2550 catch (Standard_Failure& aFail) {
2551 SetErrorCode(aFail.GetMessageString());
2554 if (aChamfer.IsNull()) {
2555 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2558 aChamfer->GetLastFunction()->SetDescription("");
2560 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2561 aFunction->SetValue(aChamferShape);
2565 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2567 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2571 // Add thickness reduction elements
2572 // at the three extremities: Left, Right and Incident
2575 if (isTRL || isTRR || isTRI) {
2576 TopoDS_Shape aResShape =
2577 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2578 theRL, theWL, theLtransL, theLthinL,
2579 theRR, theWR, theLtransR, theLthinR,
2580 theRI, theWI, theLtransI, theLthinI,
2582 aFunction->SetValue(aResShape);
2585 catch (Standard_Failure& aFail) {
2586 SetErrorCode(aFail.GetMessageString());
2591 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2592 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2593 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2594 aFunction->SetValue(aTrsf_Shape);
2596 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2597 aSeq->Append(aShape);
2602 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2603 theH, theW, 0., aSeq, aTrsf))
2607 // Get internal group.
2608 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2609 theRR, theLtransR, theRI, theLtransI,
2614 catch (Standard_Failure& aFail) {
2615 SetErrorCode(aFail.GetMessageString());
2619 //Make a Python command
2620 TCollection_AsciiString anEntry, aListRes("[");
2621 // Iterate over the sequence aSeq
2622 Standard_Integer aNbGroups = aSeq->Length();
2623 Standard_Integer i = 1;
2624 for (; i <= aNbGroups; i++) {
2625 Handle(Standard_Transient) anItem = aSeq->Value(i);
2626 if (anItem.IsNull()) continue;
2627 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2628 if (aGroup.IsNull()) continue;
2629 //Make a Python command
2630 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2631 aListRes += anEntry + ", ";
2633 aListRes.Trunc(aListRes.Length() - 2);
2635 GEOM::TPythonDump pd (aFunction);
2637 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2638 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2639 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2640 << theH << ", " << theW << ", " << theHexMesh << ", "
2641 << theP1 << ", " << theP2 << ", " << theP3;
2643 // thickness reduction
2645 pd << ", theRL=" << theRL << ", theWL=" << theWL
2646 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2648 pd << ", theRR=" << theRR << ", theWR=" << theWR
2649 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2651 pd << ", theRI=" << theRI << ", theWI=" << theWI
2652 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2661 //=============================================================================
2663 * MakePipeTShapeFillet
2664 * Create a T-shape object with specified caracteristics for the main and
2665 * the incident pipes (radius, width, half-length). A fillet is created
2666 * on the junction of the pipes.
2667 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2668 * \param theR1 Internal radius of main pipe
2669 * \param theW1 Width of main pipe
2670 * \param theL1 Half-length of main pipe
2671 * \param theR2 Internal radius of incident pipe (R2 < R1)
2672 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2673 * \param theL2 Half-length of incident pipe
2674 * \param theRF Radius of curvature of fillet.
2675 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2676 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2678 //=============================================================================
2679 Handle(TColStd_HSequenceOfTransient)
2680 AdvancedEngine_IOperations::MakePipeTShapeFillet
2681 (double theR1, double theW1, double theL1,
2682 double theR2, double theW2, double theL2,
2683 double theRL, double theWL, double theLtransL, double theLthinL,
2684 double theRR, double theWR, double theLtransR, double theLthinR,
2685 double theRI, double theWI, double theLtransI, double theLthinI,
2686 double theRF, bool theHexMesh)
2690 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2691 //Add a new shape function with parameters
2692 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2693 if (aFunction.IsNull()) return NULL;
2695 //Check if the function is set correctly
2696 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2698 AdvancedEngine_IPipeTShape aData(aFunction);
2707 aData.SetHexMesh(theHexMesh);
2709 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2710 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2711 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2713 //Compute the resulting value
2716 if (!GetSolver()->ComputeFunction(aFunction)) {
2717 SetErrorCode("TShape driver failed");
2721 catch (Standard_Failure& aFail) {
2722 SetErrorCode(aFail.GetMessageString());
2727 TopoDS_Shape aShapeShape = aShape->GetValue();
2728 TopTools_IndexedMapOfShape anEdgesIndices;
2729 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2730 // Common edges on external cylinders
2731 Handle(GEOM_Object) box_e;
2733 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2736 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2738 box_e->GetLastFunction()->SetDescription("");
2739 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2740 box_e->GetLastFunction()->SetDescription("");
2742 Handle(TColStd_HSequenceOfInteger) edges_e =
2743 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2744 box_e->GetLastFunction()->SetDescription("");
2746 if (edges_e.IsNull() || edges_e->Length() == 0) {
2747 SetErrorCode("External edges not found");
2750 int nbEdgesInFillet = 0;
2751 std::list<int> theEdges;
2752 for (int i=1; i<=edges_e->Length();i++) {
2753 int edgeID = edges_e->Value(i);
2754 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2755 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2757 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2758 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2760 theEdges.push_back(edgeID);
2764 if (theHexMesh && nbEdgesInFillet == 1)
2768 Handle(GEOM_Object) aFillet;
2770 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2772 catch (Standard_Failure& aFail) {
2773 SetErrorCode(aFail.GetMessageString());
2776 if (aFillet.IsNull()) {
2777 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2778 SetErrorCode(myLocalOperations->GetErrorCode());
2781 aFillet->GetLastFunction()->SetDescription("");
2783 TopoDS_Shape aFilletShape = aFillet->GetValue();
2785 #ifdef FILLET_FIX_TOLERANCE
2786 // VSR: 30/12/2014: temporary workaround about Fillet problem
2788 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2791 GEOMUtils::FixShapeCurves(aFilletShape);
2795 aFunction->SetValue(aFilletShape);
2798 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2799 // the following block, when enabled, leads to partitioning problems
2801 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2802 // BEGIN: Limit tolerances (debug)
2803 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2804 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2805 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2806 aCorr1->GetLastFunction()->SetDescription("");
2807 // END: Limit tolerances (debug)
2808 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2810 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2813 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2815 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2819 // Add thickness reduction elements
2820 // at the three extremities: Left, Right and Incident
2823 if (isTRL || isTRR || isTRI) {
2824 TopoDS_Shape aResShape =
2825 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2826 theRL, theWL, theLtransL, theLthinL,
2827 theRR, theWR, theLtransR, theLthinR,
2828 theRI, theWI, theLtransI, theLthinI,
2830 aFunction->SetValue(aResShape);
2833 catch (Standard_Failure& aFail) {
2834 SetErrorCode(aFail.GetMessageString());
2838 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2839 aSeq->Append(aShape);
2844 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2845 0., 0., theRF, aSeq, gp_Trsf()))
2849 // Get internal group.
2850 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2851 theRR, theLtransR, theRI, theLtransI,
2856 catch (Standard_Failure& aFail) {
2857 SetErrorCode(aFail.GetMessageString());
2861 //Make a Python command
2862 TCollection_AsciiString anEntry, aListRes("[");
2863 // Iterate over the sequence aSeq
2864 Standard_Integer aNbGroups = aSeq->Length();
2865 Standard_Integer i = 1;
2866 for (; i <= aNbGroups; i++) {
2867 Handle(Standard_Transient) anItem = aSeq->Value(i);
2868 if (anItem.IsNull()) continue;
2869 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2870 if (aGroup.IsNull()) continue;
2871 //Make a Python command
2872 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2873 aListRes += anEntry + ", ";
2875 aListRes.Trunc(aListRes.Length() - 2);
2877 GEOM::TPythonDump pd (aFunction);
2879 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2880 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2881 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2882 << theRF << ", " << theHexMesh;
2884 // thickness reduction
2886 pd << ", theRL=" << theRL << ", theWL=" << theWL
2887 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2889 pd << ", theRR=" << theRR << ", theWR=" << theWR
2890 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2892 pd << ", theRI=" << theRI << ", theWI=" << theWI
2893 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2902 //=============================================================================
2904 * MakePipeTShapeFilletWithPosition
2905 * \brief Create a T-shape object with specified caracteristics for the main and
2906 * the incident pipes (radius, width, half-length). A fillet is created
2907 * on the junction of the pipes.
2908 * The extremities of the main pipe are located on junctions points P1 and P2.
2909 * The extremity of the incident pipe is located on junction point P3.
2910 * \param theR1 Internal radius of main pipe
2911 * \param theW1 Width of main pipe
2912 * \param theL1 Half-length of main pipe
2913 * \param theR2 Internal radius of incident pipe (R2 < R1)
2914 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2915 * \param theL2 Half-length of incident pipe
2916 * \param theRF Radius of curvature of fillet
2917 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2918 * \param theP1 1st junction point of main pipe
2919 * \param theP2 2nd junction point of main pipe
2920 * \param theP3 Junction point of incident pipe
2921 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2923 //=============================================================================
2924 Handle(TColStd_HSequenceOfTransient)
2925 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2926 (double theR1, double theW1, double theL1,
2927 double theR2, double theW2, double theL2,
2928 double theRL, double theWL, double theLtransL, double theLthinL,
2929 double theRR, double theWR, double theLtransR, double theLthinR,
2930 double theRI, double theWI, double theLtransI, double theLthinI,
2931 double theRF, bool theHexMesh,
2932 Handle(GEOM_Object) theP1,
2933 Handle(GEOM_Object) theP2,
2934 Handle(GEOM_Object) theP3)
2938 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2939 //Add a new shape function with parameters
2940 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2941 if (aFunction.IsNull()) return NULL;
2943 //Check if the function is set correctly
2944 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2946 // Check new position
2947 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2951 AdvancedEngine_IPipeTShape aData(aFunction);
2960 aData.SetHexMesh(theHexMesh);
2962 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2963 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2964 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2966 //Compute the resulting value
2969 if (!GetSolver()->ComputeFunction(aFunction)) {
2970 SetErrorCode("TShape driver failed");
2974 catch (Standard_Failure& aFail) {
2975 SetErrorCode(aFail.GetMessageString());
2980 TopoDS_Shape aShapeShape = aShape->GetValue();
2981 TopTools_IndexedMapOfShape anEdgesIndices;
2982 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2983 // Common edges on external cylinders
2984 Handle(GEOM_Object) box_e;
2986 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2989 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2991 box_e->GetLastFunction()->SetDescription("");
2992 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2993 box_e->GetLastFunction()->SetDescription("");
2995 Handle(TColStd_HSequenceOfInteger) edges_e =
2996 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2997 box_e->GetLastFunction()->SetDescription("");
2999 if (edges_e.IsNull() || edges_e->Length() == 0) {
3000 SetErrorCode("External edges not found");
3003 int nbEdgesInFillet = 0;
3004 std::list<int> theEdges;
3005 for (int i=1; i<=edges_e->Length();i++) {
3006 int edgeID = edges_e->Value(i);
3007 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3008 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3010 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3011 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3013 theEdges.push_back(edgeID);
3017 if (theHexMesh && nbEdgesInFillet == 1)
3021 Handle(GEOM_Object) aFillet;
3023 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3025 catch (Standard_Failure& aFail) {
3026 SetErrorCode(aFail.GetMessageString());
3029 if (aFillet.IsNull()) {
3030 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3033 aFillet->GetLastFunction()->SetDescription("");
3035 TopoDS_Shape aFilletShape = aFillet->GetValue();
3037 #ifdef FILLET_FIX_TOLERANCE
3038 // VSR: 30/12/2014: temporary workaround about Fillet problem
3040 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3043 GEOMUtils::FixShapeCurves(aFilletShape);
3047 aFunction->SetValue(aFilletShape);
3050 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3051 // the following block, when enabled, leads to partitioning problems
3053 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3054 // BEGIN: Limit tolerances (debug)
3055 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3056 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3057 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3058 aCorr1->GetLastFunction()->SetDescription("");
3059 // END: Limit tolerances (debug)
3060 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3062 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3065 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3067 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3071 // Add thickness reduction elements
3072 // at the three extremities: Left, Right and Incident
3075 if (isTRL || isTRR || isTRI) {
3076 TopoDS_Shape aResShape =
3077 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3078 theRL, theWL, theLtransL, theLthinL,
3079 theRR, theWR, theLtransR, theLthinR,
3080 theRI, theWI, theLtransI, theLthinI,
3082 aFunction->SetValue(aResShape);
3085 catch (Standard_Failure& aFail) {
3086 SetErrorCode(aFail.GetMessageString());
3091 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3092 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3093 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3094 aFunction->SetValue(aTrsf_Shape);
3096 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3097 aSeq->Append(aShape);
3102 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3103 0., 0., theRF, aSeq, aTrsf))
3107 // Get internal group.
3108 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3109 theRR, theLtransR, theRI, theLtransI,
3114 catch (Standard_Failure& aFail) {
3115 SetErrorCode(aFail.GetMessageString());
3119 //Make a Python command
3120 TCollection_AsciiString anEntry, aListRes("[");
3121 // Iterate over the sequence aSeq
3122 Standard_Integer aNbGroups = aSeq->Length();
3123 Standard_Integer i = 1;
3124 for (; i <= aNbGroups; i++) {
3125 Handle(Standard_Transient) anItem = aSeq->Value(i);
3126 if (anItem.IsNull()) continue;
3127 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3128 if (aGroup.IsNull()) continue;
3129 //Make a Python command
3130 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3131 aListRes += anEntry + ", ";
3133 aListRes.Trunc(aListRes.Length() - 2);
3135 GEOM::TPythonDump pd (aFunction);
3137 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3138 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3139 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3140 << theRF << ", " << theHexMesh << ", "
3141 << theP1 << ", " << theP2 << ", " << theP3;
3143 // thickness reduction
3145 pd << ", theRL=" << theRL << ", theWL=" << theWL
3146 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3148 pd << ", theRR=" << theRR << ", theWR=" << theWR
3149 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3151 pd << ", theRI=" << theRI << ", theWI=" << theWI
3152 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3161 //=============================================================================
3163 * This function allows to create a disk already divided into blocks. It can be
3164 * used to create divided pipes for later meshing in hexaedra.
3165 * \param theR Radius of the disk
3166 * \param theRatio Relative size of the central square diagonal against the disk diameter
3167 * \param theOrientation Plane on which the disk will be built
3168 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3169 * \return New GEOM_Object, containing the created shape.
3171 //=============================================================================
3172 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3173 int theOrientation, int thePattern)
3177 if (theOrientation != 1 &&
3178 theOrientation != 2 &&
3179 theOrientation != 3)
3181 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3185 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDDISK);
3187 //Add a new shape function with parameters
3188 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3189 if (aFunction.IsNull()) return NULL;
3191 //Check if the function is set correctly
3192 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3194 AdvancedEngine_IDividedDisk aData (aFunction);
3197 aData.SetRatio(theRatio);
3198 aData.SetOrientation(theOrientation);
3199 aData.SetType(thePattern);
3201 //Compute the resulting value
3204 if (!GetSolver()->ComputeFunction(aFunction)) {
3205 SetErrorCode("DividedDisk driver failed");
3209 catch (Standard_Failure& aFail) {
3210 SetErrorCode(aFail.GetMessageString());
3214 std::string aPatternStr;
3219 aPatternStr = "GEOM.SQUARE";
3222 aPatternStr = "GEOM.HEXAGON";
3226 //Make a Python command
3227 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3234 //=============================================================================
3236 * This function allows to create a disk already divided into blocks. It can be
3237 * used to create divided pipes for later meshing in hexaedra.
3238 * \param theR Radius of the disk
3239 * \param theRatio Relative size of the central square diagonal against the disk diameter
3240 * \return New GEOM_Object, containing the created shape.
3242 //=============================================================================
3243 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3244 Handle(GEOM_Object) theVec,
3252 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDDISK);
3254 //Add a new shape function with parameters
3255 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3256 if (aFunction.IsNull()) return NULL;
3258 //Check if the function is set correctly
3259 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3261 AdvancedEngine_IDividedDisk aData (aFunction);
3263 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3264 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3266 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3268 aData.SetCenter(aRefPnt);
3269 aData.SetVector(aRefVec);
3272 aData.SetRatio(theRatio);
3273 aData.SetType(thePattern);
3275 //Compute the resulting value
3278 if (!GetSolver()->ComputeFunction(aFunction)) {
3279 SetErrorCode("DividedDisk driver failed");
3283 catch (Standard_Failure& aFail) {
3284 SetErrorCode(aFail.GetMessageString());
3288 std::string aPatternStr;
3293 aPatternStr = "GEOM.SQUARE";
3296 aPatternStr = "GEOM.HEXAGON";
3301 //Make a Python command
3302 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3309 //=============================================================================
3311 * Builds a cylinder prepared for hexa meshes
3312 * \param theR Radius of the cylinder
3313 * \param theH Height of the cylinder
3314 * \return New GEOM_Object, containing the created shape.
3316 //=============================================================================
3317 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3324 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDCYLINDER);
3326 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3327 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3329 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3331 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3332 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3333 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3335 std::string aPatternStr;
3340 aPatternStr = "GEOM.SQUARE";
3343 aPatternStr = "GEOM.HEXAGON";
3347 //Make a Python command
3348 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3354 //=============================================================================
3356 * Create a smoothing surface from a set of points
3357 * \param thelPoints list of points or compounds of points
3358 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3359 * \param theDegMax maximum degree of the resulting BSpline surface
3360 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3361 * \return New GEOM_Object, containing the created shape.
3363 //=============================================================================
3364 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3372 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_SMOOTHINGSURFACE);
3374 //Add a new shape function with parameters
3375 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3376 if (aFunction.IsNull()) return NULL;
3378 //Check if the function is set correctly
3379 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3381 AdvancedEngine_ISmoothingSurface aData (aFunction);
3383 int aLen = thelPoints.size();
3384 aData.SetLength(aLen);
3386 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3387 for (; it != thelPoints.end(); it++, ind++) {
3388 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3389 if (aRefObj.IsNull()) {
3390 SetErrorCode("NULL point or compound for bSplineFaceShape");
3393 aData.SetPntOrComp(ind, aRefObj);
3396 aData.SetNbMax(theNbMax);
3397 aData.SetDegMax(theDegMax);
3398 aData.SetDMax(theDMax);
3400 //Compute the resulting value
3403 if (!GetSolver()->ComputeFunction(aFunction)) {
3404 SetErrorCode("SmoothingSurface driver failed");
3408 catch (Standard_Failure& aFail) {
3409 SetErrorCode(aFail.GetMessageString());
3413 //Make a Python command
3414 GEOM::TPythonDump pd (aFunction);
3415 pd << aShape << " = geompy.MakeSmoothingSurface([";
3416 it = thelPoints.begin();
3418 while (it != thelPoints.end()) {
3419 pd << ", " << (*it++);
3423 << theDegMax << ", "