1 // Copyright (C) 2007-2019 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
468 // g / ''..| | |..'' \
470 // .---.--'.. | | | ..'--.---.
471 // |a \ '''...........''' / |
472 // |-------\------' | '------/-------.
477 // ._________________|_________________.
483 // |-----------------|-----------------|
485 // '-----------------'-----------------'
488 // "Thickness" group (a)
489 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
490 aPntA.Transform(aTrsf);
491 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
492 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
493 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
495 // "Circular quarter of pipe" group (b)
496 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
497 aPntB.Transform(aTrsf);
498 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
499 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
500 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
502 // "Circular quarter of pipe" group (c)
503 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
504 aPntC.Transform(aTrsf);
505 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
506 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
507 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
509 // "Main pipe half length" group (d)
510 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
511 aPntD.Transform(aTrsf);
512 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
513 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
514 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
516 // "Incident pipe half length" group (e)
517 double aTol10 = Precision::Confusion() * 10.;
518 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
519 aPntE.Transform(aTrsf);
520 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
521 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
522 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
524 // "Flange" group (f)
525 double aFx = - aR2Ext - aTol10;
526 if (shapeType == TSHAPE_CHAMFER)
528 else if (shapeType == TSHAPE_FILLET)
530 gp_Pnt aPntF (aFx, 0, aR1Ext);
531 aPntF.Transform(aTrsf);
532 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
533 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
534 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
536 // "Chamfer or Fillet" group (g)
537 TopoDS_Shape anEdgeG;
538 if (shapeType == TSHAPE_CHAMFER) {
539 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
540 aPntG.Transform(aTrsf);
541 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
542 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
543 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
545 else if (shapeType == TSHAPE_FILLET) {
546 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
547 aPntG.Transform(aTrsf);
548 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
549 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
550 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
553 for (int i = 1 ; i <= aNbGroups; i++) {
554 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
558 TopoDS_Shape aGroupShape = aGroup->GetValue();
559 TopTools_IndexedMapOfShape anEdgesMap;
560 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
562 if (anEdgesMap.Contains(anEdgeA)) { // a
563 aGroup->SetName("THICKNESS");
564 theSeq->Append(aGroup);
566 else if (anEdgesMap.Contains(anEdgeB)) { // b
567 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
568 theSeq->Append(aGroup);
570 else if (anEdgesMap.Contains(anEdgeC)) { // c
571 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
572 theSeq->Append(aGroup);
574 else if (anEdgesMap.Contains(anEdgeD)) { // d
575 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
576 theSeq->Append(aGroup);
578 else if (anEdgesMap.Contains(anEdgeE)) { // e
579 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
580 theSeq->Append(aGroup);
582 else if (anEdgesMap.Contains(anEdgeF)) { // f
583 aGroup->SetName("FLANGE");
584 theSeq->Append(aGroup);
586 else if (shapeType == TSHAPE_CHAMFER) { // g
587 if (anEdgesMap.Contains(anEdgeG)) {
588 aGroup->SetName("CHAMFER");
589 theSeq->Append(aGroup);
592 else if (shapeType == TSHAPE_FILLET) { // g
593 if (anEdgesMap.Contains(anEdgeG)) {
594 aGroup->SetName("FILLET");
595 theSeq->Append(aGroup);
601 // END: new groups search
604 bool circularFoundAndAdded = false;
605 bool circularFound10 = false;
606 bool incidentPipeFound = false;
607 bool mainPipeFound = false;
608 bool mainPipeFoundAndAdded = false;
609 bool radialFound =false;
610 bool flangeFound = false;
611 bool flangeFoundAndAdded = false;
612 bool chamferOrFilletFound = false;
614 for (int i = 1 ; i <= aNbGroups; i++) {
617 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
621 gp_Trsf aTrsfInv = aTrsf.Inverted();
622 TopoDS_Shape aGroupShape = aGroup->GetValue();
623 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
624 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
626 TopTools_IndexedMapOfShape anEdgesMap;
627 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
628 Standard_Integer nbEdges = anEdgesMap.Extent();
630 if (shapeType == TSHAPE_BASIC) {
631 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
633 aGroup->SetName("THICKNESS");
635 else if (nbEdges == 6) {
636 if (!circularFoundAndAdded) {
637 circularFoundAndAdded = true;
639 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
642 else if (nbEdges == 8) {
643 incidentPipeFound = true;
644 mainPipeFound = false;
648 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
650 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
651 double x=aP.X(), y=aP.Y(), z=aP.Z();
654 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
655 (Abs(y) > aR2Ext + Precision::Confusion())) {
656 incidentPipeFound = false;
659 if ( z < -Precision::Confusion()) {
660 // length of main pipe
661 mainPipeFound = true;
662 if (!mainPipeFoundAndAdded) {
663 mainPipeFoundAndAdded = true;
665 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
669 else if (Abs(x) > (theL1-Precision::Confusion())) {
670 // discretisation circulaire
672 if (!circularFoundAndAdded) {
673 circularFoundAndAdded = true;
675 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
680 if (incidentPipeFound) {
682 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
684 if (!addGroup && (!incidentPipeFound &&
688 // Flange (collerette)
691 aGroup->SetName("FLANGE");
697 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
698 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
700 aGroup->SetName("THICKNESS");
702 else if ((nbEdges == 10) || (nbEdges == 6)) {
703 if (!circularFoundAndAdded) {
705 circularFoundAndAdded = true;
706 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
708 circularFound10 = true;
711 else if (!circularFound10 && nbEdges == 10) {
712 circularFound10 = true;
714 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
717 else if (nbEdges == 8) {
718 incidentPipeFound = true;
719 mainPipeFound = true;
722 bool isNearZ0 = false;
723 bool isBelowZ0 = false;
725 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
727 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
728 double x=aP.X(), y=aP.Y(), z=aP.Z();
730 // tuy_princ_long_avant & tuy_princ_long_apres
731 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
732 // ((y <= aR1Ext + Precision::Confusion()) ||
733 // (y <= -(aR1Ext + Precision::Confusion())) ||
734 // (y <= theR1 + Precision::Confusion()) ||
735 // (y == -(theR1 + Precision::Confusion()))));
736 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
737 (fabs(y) > theR1 - Precision::Confusion() ||
738 fabs(y) < Precision::Confusion()));
741 mainPipeFound = false;
745 //if (z < Precision::Confusion() && !isMain) {
746 // flangeFound = true;
747 // if (!flangeFoundAndAdded) {
748 // flangeFoundAndAdded = true;
750 // aGroup->SetName("FLANGE");
753 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
754 if (z < - Precision::Confusion()) isBelowZ0 = true;
757 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
758 (Abs(y) > aR2Ext + Precision::Confusion())) {
759 incidentPipeFound = false;
765 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
767 if (incidentPipeFound) {
769 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
771 if (isNearZ0 && !isBelowZ0) {
773 if (!flangeFoundAndAdded) {
774 flangeFoundAndAdded = true;
776 aGroup->SetName("FLANGE");
779 if (!addGroup && (!incidentPipeFound &&
782 !chamferOrFilletFound)) {
784 chamferOrFilletFound = true;
785 if (shapeType == TSHAPE_CHAMFER)
786 aGroup->SetName("CHAMFER");
788 aGroup->SetName("FILLET");
794 // Add group to the list
796 theSeq->Append(aGroup);
804 //=============================================================================
806 * Return faces that are laying on surface.
808 //=============================================================================
809 bool AdvancedEngine_IOperations::GetFacesOnSurf
810 (const TopoDS_Shape &theShape,
811 const Handle(Geom_Surface)& theSurface,
812 const Standard_Real theTolerance,
813 TopTools_ListOfShape &theFaces)
815 GEOMAlgo_FinderShapeOn2 aFinder;
816 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
818 aClsfSurf->SetSurface(theSurface);
819 aFinder.SetShape(theShape);
820 aFinder.SetTolerance(theTolerance);
821 aFinder.SetClsf(aClsfSurf);
822 aFinder.SetShapeType(TopAbs_FACE);
823 aFinder.SetState(GEOMAlgo_ST_ON);
825 // Sets the minimal number of inner points for the faces that do not have own
826 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
828 aFinder.SetNbPntsMin(3);
829 // Sets the maximal number of inner points for edges or faces.
830 // It is useful for the cases when this number is very big (e.g =2000) to improve
831 // the performance. If this value =0, all inner points will be taken into account.
833 aFinder.SetNbPntsMax(100);
837 Standard_Integer iErr = aFinder.ErrorStatus();
838 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
840 MESSAGE(" iErr : " << iErr);
841 TCollection_AsciiString aMsg (" iErr : ");
842 aMsg += TCollection_AsciiString(iErr);
846 Standard_Integer iWrn = aFinder.WarningStatus();
847 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
849 MESSAGE(" *** iWrn : " << iWrn);
852 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
853 TopTools_ListIteratorOfListOfShape anIter (aListRes);
855 for (; anIter.More(); anIter.Next()) {
856 theFaces.Append(anIter.Value());
862 //=============================================================================
864 * Creates and returns conical face.
866 //=============================================================================
867 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
868 (const gp_Ax2 &theAxis,
869 const double theRadius,
870 const double theRadiusThin,
871 const double theHeight,
872 const gp_Trsf &theTrsf)
874 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
875 TopoDS_Shape aResult;
878 if (aMkCone.IsDone()) {
879 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
881 for (; anExp.More(); anExp.Next()) {
882 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
884 if (aFace.IsNull() == Standard_False) {
885 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
887 if (anAdaptor.GetType() == GeomAbs_Cone) {
888 // This is a conical face. Transform and return it.
889 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
891 aResult = aTransf.Shape();
901 //=============================================================================
903 * Generate the internal group of a Pipe T-Shape
905 //=============================================================================
906 bool AdvancedEngine_IOperations::MakeInternalGroup
907 (const Handle(GEOM_Object) &theShape,
908 const double theR1, const double theLen1,
909 const double theR2, const double theLen2,
910 const double theRL, double theTransLenL,
911 const double theRR, double theTransLenR,
912 const double theRI, double theTransLenI,
913 const Handle(TColStd_HSequenceOfTransient) &theSeq,
914 const gp_Trsf &theTrsf)
918 if (theShape.IsNull()) {
922 TopoDS_Shape aShape = theShape->GetValue();
924 if (aShape.IsNull()) {
925 SetErrorCode("Shape is not defined");
930 Standard_Real aMaxTol = -RealLast();
931 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
933 for (; anExp.More(); anExp.Next()) {
934 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
936 if (aVertex.IsNull() == Standard_False) {
937 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
939 if (aTol > aMaxTol) {
945 // Construct internal surfaces.
946 Standard_Integer i = 0;
947 const Standard_Integer aMaxNbSurf = 5;
948 Handle(Geom_Surface) aSurface[aMaxNbSurf];
949 TopTools_ListOfShape aConicalFaces;
950 Standard_Real aTolConf = Precision::Confusion();
952 // 1. Construct the internal surface of main pipe.
953 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
954 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
956 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
958 // 2. Construct the internal surface of incident pipe.
959 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
961 // 3. Construct the internal surface of left reduction pipe.
962 if (theRL > aTolConf) {
963 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
965 if (theTransLenL > aTolConf) {
966 // 3.1. Construct the internal surface of left transition pipe.
967 gp_Pnt aPLeft (-theLen1, 0., 0.);
968 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
969 TopoDS_Shape aConeLeft =
970 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
972 if (aConeLeft.IsNull() == Standard_False) {
973 aConicalFaces.Append(aConeLeft);
978 // 4. Construct the internal surface of right reduction pipe.
979 if (theRR > aTolConf) {
980 // There is no need to construct another cylinder of the same radius. Skip it.
981 if (Abs(theRR - theRL) > aTolConf) {
982 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
985 if (theTransLenL > aTolConf) {
986 // 4.1. Construct the internal surface of right transition pipe.
987 gp_Pnt aPRight (theLen1, 0., 0.);
988 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
989 TopoDS_Shape aConeRight =
990 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
992 if (aConeRight.IsNull() == Standard_False) {
993 aConicalFaces.Append(aConeRight);
998 // 5. Construct the internal surface of incident reduction pipe.
999 if (theRI > aTolConf) {
1000 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1002 if (theTransLenI > aTolConf) {
1003 // 5.1. Construct the internal surface of incident transition pipe.
1004 gp_Pnt aPInci (0., 0., theLen2);
1005 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1006 TopoDS_Shape aConeInci =
1007 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1009 if (aConeInci.IsNull() == Standard_False) {
1010 aConicalFaces.Append(aConeInci);
1015 // Get faces that are laying on cylindrical surfaces.
1016 TopTools_ListOfShape aFaces;
1017 gp_Trsf anInvTrsf = theTrsf.Inverted();
1019 for (i = 0; i < aMaxNbSurf; i++) {
1020 if (aSurface[i].IsNull()) {
1024 aSurface[i]->Transform(theTrsf);
1026 TopTools_ListOfShape aLocalFaces;
1028 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1033 // Check if the result contains outer cylinders.
1034 // It is required for main and incident pipes.
1035 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1037 while (anIter.More()) {
1038 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1039 Standard_Boolean isInside = Standard_False;
1041 // Get a vertex from this shape
1043 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1045 if (aVtx.IsNull() == Standard_False) {
1046 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1048 aPnt.Transform(anInvTrsf);
1051 // Check if the point is inside the main pipe.
1052 isInside = (Abs(aPnt.X()) <= theLen1);
1054 // Check if the point is inside the incident pipe.
1055 isInside = (aPnt.Z() <= theLen2);
1064 // Remove this face.
1065 aLocalFaces.Remove(anIter);
1070 aFaces.Append(aLocalFaces);
1073 // Get faces that are laying on conical faces.
1074 if (aConicalFaces.IsEmpty() == Standard_False) {
1075 Handle(GEOM_Object) aCone =
1076 GetEngine()->AddObject(GEOM_TSHAPE);
1077 Handle(GEOM_Function) aFunction =
1078 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1079 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1080 Handle(GEOM_Object) aConeFromShape;
1082 for (; aFIter.More(); aFIter.Next()) {
1083 aFunction->SetValue(aFIter.Value());
1084 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1086 if (aConeFromShape.IsNull() == Standard_False) {
1087 aConeFromShape->GetLastFunction()->SetDescription("");
1088 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1089 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1091 for (; anExp.More(); anExp.Next()) {
1092 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1094 if (aConeFace.IsNull() == Standard_False) {
1095 aFaces.Append(aConeFace);
1102 // Create a group of internal faces.
1103 if (aFaces.IsEmpty() == Standard_False) {
1104 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1106 if (aGroup.IsNull() == Standard_False) {
1107 aGroup->GetLastFunction()->SetDescription("");
1108 aGroup->SetName("INTERNAL_FACES");
1110 TopTools_IndexedMapOfShape anIndices;
1111 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1113 TopExp::MapShapes(aShape, anIndices);
1115 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1117 for (; anIter.More(); anIter.Next()) {
1118 const TopoDS_Shape &aFace = anIter.Value();
1119 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1122 aSeqIDs->Append(anIndex);
1126 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1127 aGroup->GetLastFunction()->SetDescription("");
1128 theSeq->Append(aGroup);
1137 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1138 double theR1, double theW1, double theL1,
1139 double theR2, double theW2, double theL2,
1140 double theH, double theW,
1141 double theRF, bool isNormal)
1145 // Build tools for partition operation:
1146 // 1 face and 2 planes
1148 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1149 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1150 Handle(GEOM_Object) chan_racc;
1151 Handle(GEOM_Object) vi1, vi2;
1152 Handle(GEOM_Object) Te3;
1156 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1157 Vector_Z->GetLastFunction()->SetDescription("");
1160 double aSize = 2*(theL1 + theL2);
1161 double aR1Ext = theR1 + theW1;
1162 double aR2Ext = theR2 + theW2;
1163 double theVertCylinderRadius = aR2Ext + theW + theRF;
1164 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1166 // Common edges on internal cylinder
1167 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1168 box_i->GetLastFunction()->SetDescription("");
1169 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1170 box_i->GetLastFunction()->SetDescription("");
1172 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1173 TCollection_AsciiString theDesc = aFunction->GetDescription();
1174 Handle(TColStd_HSequenceOfTransient) edges_i =
1175 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1176 // Recover previous description to get rid of Propagate dump
1177 aFunction->SetDescription(theDesc);
1178 if (edges_i.IsNull() || edges_i->Length() == 0) {
1179 SetErrorCode("Internal edges not found");
1182 for (int i=1; i<=edges_i->Length();i++) {
1183 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1184 anObj->GetLastFunction()->SetDescription("");
1186 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1188 // search for vertices located on both internal pipes
1189 aFunction = theShape->GetLastFunction();
1190 theDesc = aFunction->GetDescription();
1191 Handle(TColStd_HSequenceOfTransient) vertices_i =
1192 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1193 // Recover previous description to get rid of Propagate dump
1194 aFunction->SetDescription(theDesc);
1195 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1196 SetErrorCode("Internal vertices not found");
1200 double d1min = theR2+theW2, d2min=theR2+theW2;
1201 for (int i = 1; i <= vertices_i->Length(); i++) {
1202 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1203 v->GetLastFunction()->SetDescription("");
1204 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1205 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1206 if (Abs(aP.X()) <= Precision::Confusion()) {
1207 if (Abs(aP.Y()) < d1min) {
1209 d1min = Abs(aP.Y());
1211 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1212 if (Abs(aP.X()) < d2min) {
1214 d2min = Abs(aP.X());
1218 if (vi1.IsNull() || vi2.IsNull()) {
1219 SetErrorCode("Cannot find internal intersection vertices");
1223 std::list<Handle(GEOM_Object)> theShapes;
1226 Handle(GEOM_Object) ve1, ve2;
1227 TopoDS_Vertex vertex1, vertex2;
1229 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1230 box_e->GetLastFunction()->SetDescription("");
1231 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1232 box_e->GetLastFunction()->SetDescription("");
1234 // search for vertices located on both external pipes
1235 aFunction = theShape->GetLastFunction();
1236 theDesc = aFunction->GetDescription();
1237 Handle(TColStd_HSequenceOfTransient) vertices_e =
1238 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1239 // Recover previous description to get rid of Propagate dump
1240 aFunction->SetDescription(theDesc);
1241 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1242 SetErrorCode("External vertices not found");
1246 double d1max = 0, d2max = 0;
1247 for (int i = 1; i <= vertices_e->Length(); i++) {
1248 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1249 v->GetLastFunction()->SetDescription("");
1250 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1251 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1252 if (Abs(aP.X()) <= Precision::Confusion()) {
1253 if (Abs(aP.Y()) > d1max) {
1256 d1max = Abs(aP.Y());
1258 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1259 if (Abs(aP.X()) > d2max) {
1262 d2max = Abs(aP.X());
1266 if (ve1.IsNull() || ve2.IsNull()) {
1267 SetErrorCode("Cannot find external intersection vertices");
1270 Handle(GEOM_Object) edge_e1, edge_e2;
1272 // Common edges on external cylinder
1273 aFunction = theShape->GetLastFunction();
1274 theDesc = aFunction->GetDescription();
1275 Handle(TColStd_HSequenceOfTransient) edges_e =
1276 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1277 // Recover previous description to get rid of Propagate dump
1278 aFunction->SetDescription(theDesc);
1279 if (edges_e.IsNull() || edges_e->Length() == 0) {
1280 SetErrorCode("External edges not found");
1283 ShapeAnalysis_Edge sae;
1284 for (int i=1; i<=edges_e->Length();i++) {
1285 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1286 anObj->GetLastFunction()->SetDescription("");
1287 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1288 if ( !anEdge.IsNull() &&
1289 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1290 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1291 arete_intersect_ext = anObj;
1295 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1296 if (edge_e1.IsNull()) {
1297 SetErrorCode("Edge 1 could not be built");
1301 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1302 if (edge_e2.IsNull()) {
1303 SetErrorCode("Edge 2 could not be built");
1307 edge_e1->GetLastFunction()->SetDescription("");
1308 edge_e2->GetLastFunction()->SetDescription("");
1310 std::list<Handle(GEOM_Object)> edge_e_elist;
1311 edge_e_elist.push_back(arete_intersect_int);
1312 edge_e_elist.push_back(edge_e1);
1313 edge_e_elist.push_back(arete_intersect_ext);
1314 edge_e_elist.push_back(edge_e2);
1315 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1316 if (wire_t.IsNull()) {
1317 SetErrorCode("Impossible to build wire");
1320 wire_t->GetLastFunction()->SetDescription("");
1321 face_t = myShapesOperations->MakeFace(wire_t, false);
1322 if (face_t.IsNull()) {
1323 SetErrorCode("Impossible to build face");
1326 face_t->GetLastFunction()->SetDescription("");
1328 theShapes.push_back(theShape);
1329 theShapes.push_back(vi1);
1330 theShapes.push_back(vi2);
1331 theShapes.push_back(ve1);
1332 theShapes.push_back(ve2);
1333 theShapes.push_back(edge_e1);
1334 theShapes.push_back(edge_e2);
1335 theShapes.push_back(wire_t);
1336 theShapes.push_back(face_t);
1339 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1340 int idP1, idP2, idP3, idP4;
1343 std::vector<int> LX;
1344 std::vector<int> LY;
1345 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1346 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1347 box_e->GetLastFunction()->SetDescription("");
1348 box_e = myTransformOperations->TranslateDXDYDZ
1349 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1350 box_e->GetLastFunction()->SetDescription("");
1352 aFunction = theShape->GetLastFunction();
1353 theDesc = aFunction->GetDescription();
1354 Handle(TColStd_HSequenceOfTransient) extremVertices =
1355 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1356 // Recover previous description to get rid of Propagate dump
1357 aFunction->SetDescription(theDesc);
1359 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1361 SetErrorCode("Vertices on chamfer not found");
1363 SetErrorCode("Vertices on fillet not found");
1367 theShapes.push_back(theShape);
1368 theShapes.push_back(box_e);
1369 if (extremVertices->Length() != 6) {
1370 // for (int i=1; i<=extremVertices->Length(); i++){
1371 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1373 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1374 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1375 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1376 SetErrorCode("Bad number of vertices on chamfer found");
1380 for (int i=1; i<=extremVertices->Length(); i++){
1381 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1382 aV->GetLastFunction()->SetDescription("");
1383 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1385 if (Abs(aP.X()) <= Precision::Confusion()) {
1386 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1388 if (aP.Z()-ZX > Precision::Confusion()) {
1395 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1397 if (aP.Z() - ZY > Precision::Confusion()) {
1408 if (LX.at(0) == PZX)
1411 if (LY.at(0) == PZY)
1414 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1415 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1416 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1417 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1419 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1420 if (Cote_1.IsNull()) {
1421 SetErrorCode("Impossible to build edge in thickness");
1424 Cote_1->GetLastFunction()->SetDescription("");
1426 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1427 if (Cote_2.IsNull()) {
1428 SetErrorCode("Impossible to build edge in thickness");
1431 Cote_2->GetLastFunction()->SetDescription("");
1433 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1434 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1435 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1436 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1437 if (edge_chan_princ.IsNull()) {
1438 SetErrorCode("Impossible to find edge on main pipe");
1441 edge_chan_princ->GetLastFunction()->SetDescription("");
1443 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1444 if (edge_chan_inc.IsNull()) {
1445 SetErrorCode("Impossible to find edge on incident pipe");
1448 edge_chan_inc->GetLastFunction()->SetDescription("");
1450 std::list<Handle(GEOM_Object)> edgeList1;
1451 edgeList1.push_back(edge_chan_princ);
1452 edgeList1.push_back(Cote_1);
1453 edgeList1.push_back(arete_intersect_int);
1454 edgeList1.push_back(Cote_2);
1456 // std::cerr << "Creating wire 1" << std::endl;
1457 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1458 if (wire_t.IsNull()) {
1459 SetErrorCode("Impossible to build wire");
1462 wire_t->GetLastFunction()->SetDescription("");
1464 // std::cerr << "Creating face 1" << std::endl;
1465 face_t = myShapesOperations->MakeFace(wire_t, false);
1466 if (face_t.IsNull()) {
1467 SetErrorCode("Impossible to build face");
1470 face_t->GetLastFunction()->SetDescription("");
1471 theShapes.push_back(face_t);
1473 // Create a prism from edge_chan_inc
1474 Handle(GEOM_Object) aPrismDir = myBasicOperations->MakeVectorDXDYDZ(1., 1., 0.);
1476 if (aPrismDir.IsNull()) {
1477 SetErrorCode("Impossible to build Prism direction");
1480 aPrismDir->GetLastFunction()->SetDescription("");
1481 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, aPrismDir, theR2 + theW2);
1483 if (face_t2.IsNull()) {
1484 SetErrorCode("Impossible to build face");
1487 face_t2->GetLastFunction()->SetDescription("");
1488 theShapes.push_back(face_t2);
1492 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1493 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1494 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1495 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1496 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1497 aP0->GetLastFunction()->SetDescription("");
1498 aVZ->GetLastFunction()->SetDescription("");
1499 aVXZ->GetLastFunction()->SetDescription("");
1500 aPlnOZ->GetLastFunction()->SetDescription("");
1501 aPlnOXZ->GetLastFunction()->SetDescription("");
1502 theShapes.push_back(aPlnOZ);
1503 theShapes.push_back(aPlnOXZ);
1506 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1507 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1508 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1509 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1510 Handle(TColStd_HArray1OfInteger) theMaterials;
1512 partitionShapes->Append(theShape);
1513 theTools->Append(aPlnOZ);
1514 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1515 theTools->Append(aPlnOXZ);
1516 theTools->Append(face_t);
1518 theTools->Append(face_t2);
1520 Te3 = myBooleanOperations->MakePartition
1521 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1522 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1524 SetErrorCode("Impossible to build partition of TShape");
1527 Te3->GetLastFunction()->SetDescription("");
1529 // Last verification: result should be a block
1530 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1531 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1532 SetErrorCode("TShape is not a compound of block");
1536 // // BEGIN Compound of created shapes - Only for debug purpose
1537 // theShapes.clear();
1538 // theShapes.push_back(theShape);
1539 // theShapes.push_back(aPlnOZ);
1540 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1541 // theShapes.push_back(aPlnOXZ);
1542 // theShapes.push_back(face_t);
1544 // theShapes.push_back(face_t2);
1546 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1547 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1548 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1549 // // END Compound of created shapes - Only for debug purpose
1551 TopoDS_Shape aShape = Te3->GetValue();
1552 theShape->GetLastFunction()->SetValue(aShape);
1554 catch (Standard_Failure& aFail) {
1555 SetErrorCode(aFail.GetMessageString());
1563 // Mirror and glue faces
1564 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1565 double theR1, double theW1, double theL1,
1566 double theR2, double theW2, double theL2)
1571 double aSize = 2*(theL1 + theL2);
1572 double aR1Ext = theR1 + theW1;
1575 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1576 aP0->GetLastFunction()->SetDescription("");
1577 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1578 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1579 aVX->GetLastFunction()->SetDescription("");
1580 aVY->GetLastFunction()->SetDescription("");
1581 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1582 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1583 aPlane_OX->GetLastFunction()->SetDescription("");
1584 aPlane_OY->GetLastFunction()->SetDescription("");
1586 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1588 SetErrorCode("Impossible to build mirror of quarter TShape");
1592 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1594 SetErrorCode("Impossible to build mirror of half TShape");
1598 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1600 SetErrorCode("Impossible to build mirror of half TShape");
1604 std::list<Handle(GEOM_Object)> aShapesList;
1605 aShapesList.push_back(theShape);
1606 aShapesList.push_back(Te4);
1607 aShapesList.push_back(Te5);
1608 aShapesList.push_back(Te6);
1609 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1611 SetErrorCode("Impossible to build compound");
1615 // Copy source shape
1616 TopoDS_Shape aShapeCopy;
1617 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1618 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1620 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1621 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1623 SetErrorCode("Impossible to glue faces of TShape");
1627 TopoDS_Shape aShape = Te8->GetValue();
1628 BRepCheck_Analyzer anAna (aShape, Standard_True);
1630 if (!anAna.IsValid()) {
1631 // Try to do gluing with the tolerance equal to maximal
1632 // tolerance of vertices of the source shape.
1633 Standard_Real aTolMax = -RealLast();
1635 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1636 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1637 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1639 if (aTol > aTolMax) {
1645 Te7->GetLastFunction()->SetValue(aShapeCopy);
1646 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1649 SetErrorCode("Impossible to glue faces of TShape");
1653 aShape = Te8->GetValue();
1657 theShape->GetLastFunction()->SetValue(aShape);
1659 Te4->GetLastFunction()->SetDescription("");
1660 Te5->GetLastFunction()->SetDescription("");
1661 Te6->GetLastFunction()->SetDescription("");
1662 Te7->GetLastFunction()->SetDescription("");
1663 Te8->GetLastFunction()->SetDescription("");
1669 //=======================================================================
1670 //function : MakePipeTShapeThicknessReduction
1671 //purpose : Static method. Add thiskness reduction elements at the three
1672 // open ends of the T-Shape.
1673 //=======================================================================
1674 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1675 (TopoDS_Shape theShape,
1676 double r1, double w1, double l1,
1677 double r2, double w2, double l2,
1678 double rL, double wL, double ltransL, double lthinL,
1679 double rR, double wR, double ltransR, double lthinR,
1680 double rI, double wI, double ltransI, double lthinI,
1681 bool fuseReductions)
1683 // Add thickness reduction elements
1684 // at the three extremities: Left, Right and Incident
1686 // ---------------------.
1688 // ---------------------. \
1689 // ^ \ '-----------------.
1691 // | '-----------------'
1693 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1696 TopoDS_Shape aResult = theShape;
1697 double aTol = Precision::Confusion();
1699 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1701 // Left reduction (rL, wL, ltransL, lthinL)
1702 if (rL > aTol && wL > aTol && ltransL > aTol) {
1703 gp_Pnt aPLeft (-l1, 0, 0);
1704 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1705 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1706 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1708 if (fuseReductions) {
1709 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1710 if (!fuseL.IsDone())
1711 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1712 aResult = fuseL.Shape();
1719 B.Add(C, aReductionLeft);
1725 if (rR > aTol && wR > aTol && ltransR > aTol) {
1726 gp_Pnt aPRight (l1, 0, 0);
1727 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1728 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1729 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1731 if (fuseReductions) {
1732 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1733 if (!fuseR.IsDone())
1734 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1735 aResult = fuseR.Shape();
1742 B.Add(C, aReductionRight);
1747 // Incident reduction
1748 if (rI > aTol && wI > aTol && ltransI > aTol) {
1749 gp_Pnt aPInci (0, 0, l2);
1750 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1751 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1752 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1754 if (fuseReductions) {
1755 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1756 if (!fuseInci.IsDone())
1757 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1758 aResult = fuseInci.Shape();
1765 B.Add(C, aReductionInci);
1770 // Get rid of extra compounds
1771 TopTools_ListOfShape listShapeRes;
1772 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1773 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1775 if (!fuseReductions && listShapeRes.Extent() > 1) {
1776 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1781 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1782 for (; itSub.More(); itSub.Next())
1783 B.Add(C, itSub.Value());
1786 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1792 //=======================================================================
1793 //function : MakeThicknessReduction
1794 //purpose : Static method. Create one thickness reduction element.
1795 //=======================================================================
1796 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1797 const double R, const double W,
1798 const double Rthin, const double Wthin,
1799 const double Ltrans, const double Lthin,
1802 double aTol = Precision::Confusion();
1803 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1804 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1806 bool isThinPart = (Lthin > aTol);
1811 // ^ \ '-----------------.
1813 // | '-----------------'
1815 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1818 double RExt = R + W;
1819 double RthinExt = Rthin + Wthin;
1821 gp_Dir aNormal = theAxes.Direction();
1822 gp_Dir anXDir = theAxes.XDirection();
1823 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1824 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1826 // Build the transition part
1827 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1828 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1831 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1832 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1833 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1835 StdFail_NotDone::Raise("Couldn't build transition part of thickness reduction");
1836 TopoDS_Shape aReduction = cut1.Shape();
1838 // Build the thin part, if required
1839 TopoDS_Shape aThinPart;
1841 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1842 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1845 if (!CExt.IsDone() || !CInt.IsDone())
1846 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1847 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1849 StdFail_NotDone::Raise("Couldn't build thin part of thickness reduction");
1850 aThinPart = cut2.Shape();
1856 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1857 if (!fuse1.IsDone())
1858 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1859 aReduction = fuse1.Shape();
1863 // Partition the reduction on blocks
1864 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1865 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1866 gp_Pln aPln1 (anAxesPln1);
1867 gp_Pln aPln2 (anAxesPln2);
1868 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1869 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1870 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1872 GEOMAlgo_Splitter PS;
1873 PS.AddArgument(aReduction);
1875 PS.AddArgument(aThinPart);
1878 PS.SetLimit(TopAbs_SOLID);
1881 aReduction = PS.Shape();
1887 //=============================================================================
1890 * \brief Create a T-shape object with specified caracteristics for the main and
1891 * the incident pipes (radius, width, half-length).
1892 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1893 * \param theR1 Internal radius of main pipe
1894 * \param theW1 Width of main pipe
1895 * \param theL1 Half-length of main pipe
1896 * \param theR2 Internal radius of incident pipe (R2 < R1)
1897 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1898 * \param theL2 Half-length of incident pipe
1899 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1900 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1902 //=============================================================================
1903 Handle(TColStd_HSequenceOfTransient)
1904 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1905 double theR2, double theW2, double theL2,
1906 double theRL, double theWL, double theLtransL, double theLthinL,
1907 double theRR, double theWR, double theLtransR, double theLthinR,
1908 double theRI, double theWI, double theLtransI, double theLthinI,
1911 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1914 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
1916 //Add a new shape function with parameters
1917 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1918 if (aFunction.IsNull()) return NULL;
1920 //Check if the function is set correctly
1921 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1923 AdvancedEngine_IPipeTShape aData (aFunction);
1931 aData.SetHexMesh(theHexMesh);
1933 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1934 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1935 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1937 //Compute the resulting value
1940 if (!GetSolver()->ComputeFunction(aFunction)) {
1941 SetErrorCode("TShape driver failed");
1946 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1948 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1952 if (isTRL || isTRR || isTRI) {
1953 // Add thickness reduction elements
1954 // at the three extremities: Left, Right and Incident
1955 TopoDS_Shape aResShape =
1956 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1957 theRL, theWL, theLtransL, theLthinL,
1958 theRR, theWR, theLtransR, theLthinR,
1959 theRI, theWI, theLtransI, theLthinI,
1961 aFunction->SetValue(aResShape);
1964 catch (Standard_Failure& aFail) {
1965 SetErrorCode(aFail.GetMessageString());
1969 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1970 aSeq->Append(aShape);
1975 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1976 0., 0., 0., aSeq, gp_Trsf()))
1980 // Get internal group.
1981 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
1982 theRR, theLtransR, theRI, theLtransI,
1987 catch (Standard_Failure& aFail) {
1988 SetErrorCode(aFail.GetMessageString());
1992 //Make a Python command
1993 TCollection_AsciiString anEntry, aListRes("[");
1994 // Iterate over the sequence aSeq
1995 Standard_Integer aNbGroups = aSeq->Length();
1996 Standard_Integer i = 1;
1997 for (; i <= aNbGroups; i++) {
1998 Handle(Standard_Transient) anItem = aSeq->Value(i);
1999 if (anItem.IsNull()) continue;
2000 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2001 if (aGroup.IsNull()) continue;
2002 //Make a Python command
2003 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2004 aListRes += anEntry + ", ";
2006 aListRes.Trunc(aListRes.Length() - 2);
2008 GEOM::TPythonDump pd (aFunction);
2010 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2011 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2012 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2015 // thickness reduction
2017 pd << ", theRL=" << theRL << ", theWL=" << theWL
2018 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2020 pd << ", theRR=" << theRR << ", theWR=" << theWR
2021 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2023 pd << ", theRI=" << theRI << ", theWI=" << theWI
2024 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2033 //=============================================================================
2035 * MakePipeTShapeWithPosition
2036 * Create a T-shape object with specified caracteristics for the main and
2037 * the incident pipes (radius, width, half-length).
2038 * The extremities of the main pipe are located on junctions points P1 and P2.
2039 * The extremity of the incident pipe is located on junction point P3.
2040 * \param theR1 Internal radius of main pipe
2041 * \param theW1 Width of main pipe
2042 * \param theL1 Half-length of main pipe
2043 * \param theR2 Internal radius of incident pipe (R2 < R1)
2044 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2045 * \param theL2 Half-length of incident pipe
2046 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2047 * \param theP1 1st junction point of main pipe
2048 * \param theP2 2nd junction point of main pipe
2049 * \param theP3 Junction point of incident pipe
2050 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2052 //=============================================================================
2053 Handle(TColStd_HSequenceOfTransient)
2054 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2055 (double theR1, double theW1, double theL1,
2056 double theR2, double theW2, double theL2,
2057 double theRL, double theWL, double theLtransL, double theLthinL,
2058 double theRR, double theWR, double theLtransR, double theLthinR,
2059 double theRI, double theWI, double theLtransI, double theLthinI,
2061 Handle(GEOM_Object) theP1,
2062 Handle(GEOM_Object) theP2,
2063 Handle(GEOM_Object) theP3)
2067 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2071 //Add a new shape function with parameters
2072 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2073 if (aFunction.IsNull()) return NULL;
2075 //Check if the function is set correctly
2076 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2078 // Check new position
2079 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2083 AdvancedEngine_IPipeTShape aData(aFunction);
2091 aData.SetHexMesh(theHexMesh);
2093 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2094 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2095 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2097 //Compute the resulting value
2100 if (!GetSolver()->ComputeFunction(aFunction)) {
2101 SetErrorCode("TShape driver failed");
2106 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2108 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2112 if (isTRL || isTRR || isTRI) {
2113 // Add thickness reduction elements
2114 // at the three extremities: Left, Right and Incident
2115 TopoDS_Shape aResShape =
2116 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2117 theRL, theWL, theLtransL, theLthinL,
2118 theRR, theWR, theLtransR, theLthinR,
2119 theRI, theWI, theLtransI, theLthinI,
2121 aFunction->SetValue(aResShape);
2124 catch (Standard_Failure& aFail) {
2125 SetErrorCode(aFail.GetMessageString());
2129 TopoDS_Shape Te = aShape->GetValue();
2132 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2133 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2134 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2135 aFunction->SetValue(aTrsf_Shape);
2137 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2138 aSeq->Append(aShape);
2143 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2144 0., 0., 0., aSeq, aTrsf)) {
2149 // Get internal group.
2150 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2151 theRR, theLtransR, theRI, theLtransI,
2156 catch (Standard_Failure& aFail) {
2157 SetErrorCode(aFail.GetMessageString());
2161 //Make a Python command
2162 TCollection_AsciiString anEntry, aListRes("[");
2163 // Iterate over the sequence aSeq
2164 Standard_Integer aNbGroups = aSeq->Length();
2165 Standard_Integer i = 1;
2166 for (; i <= aNbGroups; i++) {
2167 Handle(Standard_Transient) anItem = aSeq->Value(i);
2168 if (anItem.IsNull()) continue;
2169 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2170 if (aGroup.IsNull()) continue;
2171 //Make a Python command
2172 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2173 aListRes += anEntry + ", ";
2175 aListRes.Trunc(aListRes.Length() - 2);
2177 GEOM::TPythonDump pd (aFunction);
2179 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2180 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2181 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2182 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2184 // thickness reduction
2186 pd << ", theRL=" << theRL << ", theWL=" << theWL
2187 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2189 pd << ", theRR=" << theRR << ", theWR=" << theWR
2190 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2192 pd << ", theRI=" << theRI << ", theWI=" << theWI
2193 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2202 //=============================================================================
2204 * MakePipeTShapeChamfer
2205 * Create a T-shape object with specified caracteristics for the main and
2206 * the incident pipes (radius, width, half-length). A chamfer is created
2207 * on the junction of the pipes.
2208 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2209 * \param theR1 Internal radius of main pipe
2210 * \param theW1 Width of main pipe
2211 * \param theL1 Half-length of main pipe
2212 * \param theR2 Internal radius of incident pipe (R2 < R1)
2213 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2214 * \param theL2 Half-length of incident pipe
2215 * \param theH Height of chamfer.
2216 * \param theW Width of chamfer.
2217 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2218 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2220 //=============================================================================
2221 Handle(TColStd_HSequenceOfTransient)
2222 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2223 (double theR1, double theW1, double theL1,
2224 double theR2, double theW2, double theL2,
2225 double theRL, double theWL, double theLtransL, double theLthinL,
2226 double theRR, double theWR, double theLtransR, double theLthinR,
2227 double theRI, double theWI, double theLtransI, double theLthinI,
2228 double theH, double theW,
2233 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2234 //Add a new shape function with parameters
2235 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2236 if (aFunction.IsNull()) return NULL;
2238 //Check if the function is set correctly
2239 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2241 AdvancedEngine_IPipeTShape aData(aFunction);
2251 aData.SetHexMesh(theHexMesh);
2253 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2254 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2255 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2257 //Compute the resulting value
2260 if (!GetSolver()->ComputeFunction(aFunction)) {
2261 SetErrorCode("TShape driver failed");
2265 catch (Standard_Failure& aFail) {
2266 SetErrorCode(aFail.GetMessageString());
2271 TopoDS_Shape aShapeShape = aShape->GetValue();
2272 TopTools_IndexedMapOfShape anEdgesIndices;
2273 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2274 // Common edges on external cylinders
2275 Handle(GEOM_Object) box_e;
2277 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2280 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2282 box_e->GetLastFunction()->SetDescription("");
2283 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2284 box_e->GetLastFunction()->SetDescription("");
2286 Handle(TColStd_HSequenceOfInteger) edges_e =
2287 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2288 box_e->GetLastFunction()->SetDescription("");
2290 if (edges_e.IsNull() || edges_e->Length() == 0) {
2291 SetErrorCode("External edges not found");
2294 int nbEdgesInChamfer = 0;
2295 std::list<int> theEdges;
2296 for (int i=1; i<=edges_e->Length();i++) {
2297 int edgeID = edges_e->Value(i);
2298 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2299 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2303 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2304 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2305 nbEdgesInChamfer ++;
2306 theEdges.push_back(edgeID);
2310 if (theHexMesh && nbEdgesInChamfer == 1)
2313 Handle(GEOM_Object) aChamfer;
2315 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2317 catch (Standard_Failure& aFail) {
2318 SetErrorCode(aFail.GetMessageString());
2321 if (aChamfer.IsNull()) {
2322 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2325 aChamfer->GetLastFunction()->SetDescription("");
2327 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2328 aFunction->SetValue(aChamferShape);
2332 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2334 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2338 // Add thickness reduction elements
2339 // at the three extremities: Left, Right and Incident
2342 if (isTRL || isTRR || isTRI) {
2343 TopoDS_Shape aResShape =
2344 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2345 theRL, theWL, theLtransL, theLthinL,
2346 theRR, theWR, theLtransR, theLthinR,
2347 theRI, theWI, theLtransI, theLthinI,
2349 aFunction->SetValue(aResShape);
2352 catch (Standard_Failure& aFail) {
2353 SetErrorCode(aFail.GetMessageString());
2357 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2358 aSeq->Append(aShape);
2363 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2364 theH, theW, 0., aSeq, gp_Trsf()))
2368 // Get internal group.
2369 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2370 theRR, theLtransR, theRI, theLtransI,
2375 catch (Standard_Failure& aFail) {
2376 SetErrorCode(aFail.GetMessageString());
2380 //Make a Python command
2381 TCollection_AsciiString anEntry, aListRes("[");
2382 // Iterate over the sequence aSeq
2383 Standard_Integer aNbGroups = aSeq->Length();
2384 Standard_Integer i = 1;
2385 for (; i <= aNbGroups; i++) {
2386 Handle(Standard_Transient) anItem = aSeq->Value(i);
2387 if (anItem.IsNull()) continue;
2388 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2389 if (aGroup.IsNull()) continue;
2390 //Make a Python command
2391 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2392 aListRes += anEntry + ", ";
2394 aListRes.Trunc(aListRes.Length() - 2);
2396 GEOM::TPythonDump pd (aFunction);
2398 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2399 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2400 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2401 << theH << ", " << theW << ", " << theHexMesh;
2403 // thickness reduction
2405 pd << ", theRL=" << theRL << ", theWL=" << theWL
2406 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2408 pd << ", theRR=" << theRR << ", theWR=" << theWR
2409 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2411 pd << ", theRI=" << theRI << ", theWI=" << theWI
2412 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2421 //=============================================================================
2423 * MakePipeTShapeChamferWithPosition
2424 * Create a T-shape object with specified caracteristics for the main and
2425 * the incident pipes (radius, width, half-length). A chamfer is created
2426 * on the junction of the pipes.
2427 * The extremities of the main pipe are located on junctions points P1 and P2.
2428 * The extremity of the incident pipe is located on junction point P3.
2429 * \param theR1 Internal radius of main pipe
2430 * \param theW1 Width of main pipe
2431 * \param theL1 Half-length of main pipe
2432 * \param theR2 Internal radius of incident pipe (R2 < R1)
2433 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2434 * \param theL2 Half-length of incident pipe
2435 * \param theH Height of chamfer.
2436 * \param theW Width of chamfer.
2437 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2438 * \param theP1 1st junction point of main pipe
2439 * \param theP2 2nd junction point of main pipe
2440 * \param theP3 Junction point of incident pipe
2441 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2443 //=============================================================================
2444 Handle(TColStd_HSequenceOfTransient)
2445 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2446 (double theR1, double theW1, double theL1,
2447 double theR2, double theW2, double theL2,
2448 double theRL, double theWL, double theLtransL, double theLthinL,
2449 double theRR, double theWR, double theLtransR, double theLthinR,
2450 double theRI, double theWI, double theLtransI, double theLthinI,
2451 double theH, double theW,
2453 Handle(GEOM_Object) theP1,
2454 Handle(GEOM_Object) theP2,
2455 Handle(GEOM_Object) theP3)
2459 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2460 //Add a new shape function with parameters
2461 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2462 if (aFunction.IsNull()) return NULL;
2464 //Check if the function is set correctly
2465 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2467 // Check new position
2468 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2472 AdvancedEngine_IPipeTShape aData(aFunction);
2482 aData.SetHexMesh(theHexMesh);
2484 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2485 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2486 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2488 //Compute the resulting value
2491 if (!GetSolver()->ComputeFunction(aFunction)) {
2492 SetErrorCode("TShape driver failed");
2496 catch (Standard_Failure& aFail) {
2497 SetErrorCode(aFail.GetMessageString());
2502 TopoDS_Shape aShapeShape = aShape->GetValue();
2503 TopTools_IndexedMapOfShape anEdgesIndices;
2504 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2505 // Common edges on external cylinders
2506 Handle(GEOM_Object) box_e;
2508 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2511 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2513 box_e->GetLastFunction()->SetDescription("");
2514 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2515 box_e->GetLastFunction()->SetDescription("");
2517 Handle(TColStd_HSequenceOfInteger) edges_e =
2518 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2519 box_e->GetLastFunction()->SetDescription("");
2521 if (edges_e.IsNull() || edges_e->Length() == 0) {
2522 SetErrorCode("External edges not found");
2525 int nbEdgesInChamfer = 0;
2526 std::list<int> theEdges;
2527 for (int i=1; i<=edges_e->Length();i++) {
2528 int edgeID = edges_e->Value(i);
2529 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2530 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2532 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2533 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2534 nbEdgesInChamfer ++;
2535 theEdges.push_back(edgeID);
2539 if (theHexMesh && nbEdgesInChamfer == 1)
2542 Handle(GEOM_Object) aChamfer;
2544 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2546 catch (Standard_Failure& aFail) {
2547 SetErrorCode(aFail.GetMessageString());
2550 if (aChamfer.IsNull()) {
2551 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2554 aChamfer->GetLastFunction()->SetDescription("");
2556 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2557 aFunction->SetValue(aChamferShape);
2561 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2563 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2567 // Add thickness reduction elements
2568 // at the three extremities: Left, Right and Incident
2571 if (isTRL || isTRR || isTRI) {
2572 TopoDS_Shape aResShape =
2573 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2574 theRL, theWL, theLtransL, theLthinL,
2575 theRR, theWR, theLtransR, theLthinR,
2576 theRI, theWI, theLtransI, theLthinI,
2578 aFunction->SetValue(aResShape);
2581 catch (Standard_Failure& aFail) {
2582 SetErrorCode(aFail.GetMessageString());
2587 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2588 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2589 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2590 aFunction->SetValue(aTrsf_Shape);
2592 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2593 aSeq->Append(aShape);
2598 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2599 theH, theW, 0., aSeq, aTrsf))
2603 // Get internal group.
2604 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2605 theRR, theLtransR, theRI, theLtransI,
2610 catch (Standard_Failure& aFail) {
2611 SetErrorCode(aFail.GetMessageString());
2615 //Make a Python command
2616 TCollection_AsciiString anEntry, aListRes("[");
2617 // Iterate over the sequence aSeq
2618 Standard_Integer aNbGroups = aSeq->Length();
2619 Standard_Integer i = 1;
2620 for (; i <= aNbGroups; i++) {
2621 Handle(Standard_Transient) anItem = aSeq->Value(i);
2622 if (anItem.IsNull()) continue;
2623 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2624 if (aGroup.IsNull()) continue;
2625 //Make a Python command
2626 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2627 aListRes += anEntry + ", ";
2629 aListRes.Trunc(aListRes.Length() - 2);
2631 GEOM::TPythonDump pd (aFunction);
2633 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2634 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2635 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2636 << theH << ", " << theW << ", " << theHexMesh << ", "
2637 << theP1 << ", " << theP2 << ", " << theP3;
2639 // thickness reduction
2641 pd << ", theRL=" << theRL << ", theWL=" << theWL
2642 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2644 pd << ", theRR=" << theRR << ", theWR=" << theWR
2645 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2647 pd << ", theRI=" << theRI << ", theWI=" << theWI
2648 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2657 //=============================================================================
2659 * MakePipeTShapeFillet
2660 * Create a T-shape object with specified caracteristics for the main and
2661 * the incident pipes (radius, width, half-length). A fillet is created
2662 * on the junction of the pipes.
2663 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2664 * \param theR1 Internal radius of main pipe
2665 * \param theW1 Width of main pipe
2666 * \param theL1 Half-length of main pipe
2667 * \param theR2 Internal radius of incident pipe (R2 < R1)
2668 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2669 * \param theL2 Half-length of incident pipe
2670 * \param theRF Radius of curvature of fillet.
2671 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2672 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2674 //=============================================================================
2675 Handle(TColStd_HSequenceOfTransient)
2676 AdvancedEngine_IOperations::MakePipeTShapeFillet
2677 (double theR1, double theW1, double theL1,
2678 double theR2, double theW2, double theL2,
2679 double theRL, double theWL, double theLtransL, double theLthinL,
2680 double theRR, double theWR, double theLtransR, double theLthinR,
2681 double theRI, double theWI, double theLtransI, double theLthinI,
2682 double theRF, bool theHexMesh)
2686 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2687 //Add a new shape function with parameters
2688 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2689 if (aFunction.IsNull()) return NULL;
2691 //Check if the function is set correctly
2692 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2694 AdvancedEngine_IPipeTShape aData(aFunction);
2703 aData.SetHexMesh(theHexMesh);
2705 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2706 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2707 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2709 //Compute the resulting value
2712 if (!GetSolver()->ComputeFunction(aFunction)) {
2713 SetErrorCode("TShape driver failed");
2717 catch (Standard_Failure& aFail) {
2718 SetErrorCode(aFail.GetMessageString());
2723 TopoDS_Shape aShapeShape = aShape->GetValue();
2724 TopTools_IndexedMapOfShape anEdgesIndices;
2725 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2726 // Common edges on external cylinders
2727 Handle(GEOM_Object) box_e;
2729 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2732 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2734 box_e->GetLastFunction()->SetDescription("");
2735 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2736 box_e->GetLastFunction()->SetDescription("");
2738 Handle(TColStd_HSequenceOfInteger) edges_e =
2739 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2740 box_e->GetLastFunction()->SetDescription("");
2742 if (edges_e.IsNull() || edges_e->Length() == 0) {
2743 SetErrorCode("External edges not found");
2746 int nbEdgesInFillet = 0;
2747 std::list<int> theEdges;
2748 for (int i=1; i<=edges_e->Length();i++) {
2749 int edgeID = edges_e->Value(i);
2750 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2751 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2753 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2754 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2756 theEdges.push_back(edgeID);
2760 if (theHexMesh && nbEdgesInFillet == 1)
2764 Handle(GEOM_Object) aFillet;
2766 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2768 catch (Standard_Failure& aFail) {
2769 SetErrorCode(aFail.GetMessageString());
2772 if (aFillet.IsNull()) {
2773 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2774 SetErrorCode(myLocalOperations->GetErrorCode());
2777 aFillet->GetLastFunction()->SetDescription("");
2779 TopoDS_Shape aFilletShape = aFillet->GetValue();
2781 #ifdef FILLET_FIX_TOLERANCE
2782 // VSR: 30/12/2014: temporary workaround about Fillet problem
2784 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2787 GEOMUtils::FixShapeCurves(aFilletShape);
2791 aFunction->SetValue(aFilletShape);
2794 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2795 // the following block, when enabled, leads to partitioning problems
2797 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2798 // BEGIN: Limit tolerances (debug)
2799 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2800 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2801 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2802 aCorr1->GetLastFunction()->SetDescription("");
2803 // END: Limit tolerances (debug)
2804 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2806 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2809 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2811 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2815 // Add thickness reduction elements
2816 // at the three extremities: Left, Right and Incident
2819 if (isTRL || isTRR || isTRI) {
2820 TopoDS_Shape aResShape =
2821 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2822 theRL, theWL, theLtransL, theLthinL,
2823 theRR, theWR, theLtransR, theLthinR,
2824 theRI, theWI, theLtransI, theLthinI,
2826 aFunction->SetValue(aResShape);
2829 catch (Standard_Failure& aFail) {
2830 SetErrorCode(aFail.GetMessageString());
2834 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2835 aSeq->Append(aShape);
2840 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2841 0., 0., theRF, aSeq, gp_Trsf()))
2845 // Get internal group.
2846 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2847 theRR, theLtransR, theRI, theLtransI,
2852 catch (Standard_Failure& aFail) {
2853 SetErrorCode(aFail.GetMessageString());
2857 //Make a Python command
2858 TCollection_AsciiString anEntry, aListRes("[");
2859 // Iterate over the sequence aSeq
2860 Standard_Integer aNbGroups = aSeq->Length();
2861 Standard_Integer i = 1;
2862 for (; i <= aNbGroups; i++) {
2863 Handle(Standard_Transient) anItem = aSeq->Value(i);
2864 if (anItem.IsNull()) continue;
2865 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2866 if (aGroup.IsNull()) continue;
2867 //Make a Python command
2868 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2869 aListRes += anEntry + ", ";
2871 aListRes.Trunc(aListRes.Length() - 2);
2873 GEOM::TPythonDump pd (aFunction);
2875 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2876 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2877 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2878 << theRF << ", " << theHexMesh;
2880 // thickness reduction
2882 pd << ", theRL=" << theRL << ", theWL=" << theWL
2883 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2885 pd << ", theRR=" << theRR << ", theWR=" << theWR
2886 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2888 pd << ", theRI=" << theRI << ", theWI=" << theWI
2889 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2898 //=============================================================================
2900 * MakePipeTShapeFilletWithPosition
2901 * \brief Create a T-shape object with specified caracteristics for the main and
2902 * the incident pipes (radius, width, half-length). A fillet is created
2903 * on the junction of the pipes.
2904 * The extremities of the main pipe are located on junctions points P1 and P2.
2905 * The extremity of the incident pipe is located on junction point P3.
2906 * \param theR1 Internal radius of main pipe
2907 * \param theW1 Width of main pipe
2908 * \param theL1 Half-length of main pipe
2909 * \param theR2 Internal radius of incident pipe (R2 < R1)
2910 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2911 * \param theL2 Half-length of incident pipe
2912 * \param theRF Radius of curvature of fillet
2913 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2914 * \param theP1 1st junction point of main pipe
2915 * \param theP2 2nd junction point of main pipe
2916 * \param theP3 Junction point of incident pipe
2917 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2919 //=============================================================================
2920 Handle(TColStd_HSequenceOfTransient)
2921 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2922 (double theR1, double theW1, double theL1,
2923 double theR2, double theW2, double theL2,
2924 double theRL, double theWL, double theLtransL, double theLthinL,
2925 double theRR, double theWR, double theLtransR, double theLthinR,
2926 double theRI, double theWI, double theLtransI, double theLthinI,
2927 double theRF, bool theHexMesh,
2928 Handle(GEOM_Object) theP1,
2929 Handle(GEOM_Object) theP2,
2930 Handle(GEOM_Object) theP3)
2934 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_TSHAPE);
2935 //Add a new shape function with parameters
2936 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2937 if (aFunction.IsNull()) return NULL;
2939 //Check if the function is set correctly
2940 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2942 // Check new position
2943 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2947 AdvancedEngine_IPipeTShape aData(aFunction);
2956 aData.SetHexMesh(theHexMesh);
2958 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2959 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2960 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2962 //Compute the resulting value
2965 if (!GetSolver()->ComputeFunction(aFunction)) {
2966 SetErrorCode("TShape driver failed");
2970 catch (Standard_Failure& aFail) {
2971 SetErrorCode(aFail.GetMessageString());
2976 TopoDS_Shape aShapeShape = aShape->GetValue();
2977 TopTools_IndexedMapOfShape anEdgesIndices;
2978 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2979 // Common edges on external cylinders
2980 Handle(GEOM_Object) box_e;
2982 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2985 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2987 box_e->GetLastFunction()->SetDescription("");
2988 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2989 box_e->GetLastFunction()->SetDescription("");
2991 Handle(TColStd_HSequenceOfInteger) edges_e =
2992 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2993 box_e->GetLastFunction()->SetDescription("");
2995 if (edges_e.IsNull() || edges_e->Length() == 0) {
2996 SetErrorCode("External edges not found");
2999 int nbEdgesInFillet = 0;
3000 std::list<int> theEdges;
3001 for (int i=1; i<=edges_e->Length();i++) {
3002 int edgeID = edges_e->Value(i);
3003 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3004 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3006 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3007 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3009 theEdges.push_back(edgeID);
3013 if (theHexMesh && nbEdgesInFillet == 1)
3017 Handle(GEOM_Object) aFillet;
3019 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3021 catch (Standard_Failure& aFail) {
3022 SetErrorCode(aFail.GetMessageString());
3025 if (aFillet.IsNull()) {
3026 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3029 aFillet->GetLastFunction()->SetDescription("");
3031 TopoDS_Shape aFilletShape = aFillet->GetValue();
3033 #ifdef FILLET_FIX_TOLERANCE
3034 // VSR: 30/12/2014: temporary workaround about Fillet problem
3036 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3039 GEOMUtils::FixShapeCurves(aFilletShape);
3043 aFunction->SetValue(aFilletShape);
3046 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3047 // the following block, when enabled, leads to partitioning problems
3049 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3050 // BEGIN: Limit tolerances (debug)
3051 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3052 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3053 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3054 aCorr1->GetLastFunction()->SetDescription("");
3055 // END: Limit tolerances (debug)
3056 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3058 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3061 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3063 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3067 // Add thickness reduction elements
3068 // at the three extremities: Left, Right and Incident
3071 if (isTRL || isTRR || isTRI) {
3072 TopoDS_Shape aResShape =
3073 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3074 theRL, theWL, theLtransL, theLthinL,
3075 theRR, theWR, theLtransR, theLthinR,
3076 theRI, theWI, theLtransI, theLthinI,
3078 aFunction->SetValue(aResShape);
3081 catch (Standard_Failure& aFail) {
3082 SetErrorCode(aFail.GetMessageString());
3087 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3088 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3089 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3090 aFunction->SetValue(aTrsf_Shape);
3092 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3093 aSeq->Append(aShape);
3098 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3099 0., 0., theRF, aSeq, aTrsf))
3103 // Get internal group.
3104 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3105 theRR, theLtransR, theRI, theLtransI,
3110 catch (Standard_Failure& aFail) {
3111 SetErrorCode(aFail.GetMessageString());
3115 //Make a Python command
3116 TCollection_AsciiString anEntry, aListRes("[");
3117 // Iterate over the sequence aSeq
3118 Standard_Integer aNbGroups = aSeq->Length();
3119 Standard_Integer i = 1;
3120 for (; i <= aNbGroups; i++) {
3121 Handle(Standard_Transient) anItem = aSeq->Value(i);
3122 if (anItem.IsNull()) continue;
3123 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3124 if (aGroup.IsNull()) continue;
3125 //Make a Python command
3126 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3127 aListRes += anEntry + ", ";
3129 aListRes.Trunc(aListRes.Length() - 2);
3131 GEOM::TPythonDump pd (aFunction);
3133 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3134 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3135 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3136 << theRF << ", " << theHexMesh << ", "
3137 << theP1 << ", " << theP2 << ", " << theP3;
3139 // thickness reduction
3141 pd << ", theRL=" << theRL << ", theWL=" << theWL
3142 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3144 pd << ", theRR=" << theRR << ", theWR=" << theWR
3145 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3147 pd << ", theRI=" << theRI << ", theWI=" << theWI
3148 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3157 //=============================================================================
3159 * This function allows to create a disk already divided into blocks. It can be
3160 * used to create divided pipes for later meshing in hexaedra.
3161 * \param theR Radius of the disk
3162 * \param theRatio Relative size of the central square diagonal against the disk diameter
3163 * \param theOrientation Plane on which the disk will be built
3164 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3165 * \return New GEOM_Object, containing the created shape.
3167 //=============================================================================
3168 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3169 int theOrientation, int thePattern)
3173 if (theOrientation != 1 &&
3174 theOrientation != 2 &&
3175 theOrientation != 3)
3177 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3181 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDDISK);
3183 //Add a new shape function with parameters
3184 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3185 if (aFunction.IsNull()) return NULL;
3187 //Check if the function is set correctly
3188 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3190 AdvancedEngine_IDividedDisk aData (aFunction);
3193 aData.SetRatio(theRatio);
3194 aData.SetOrientation(theOrientation);
3195 aData.SetType(thePattern);
3197 //Compute the resulting value
3200 if (!GetSolver()->ComputeFunction(aFunction)) {
3201 SetErrorCode("DividedDisk driver failed");
3205 catch (Standard_Failure& aFail) {
3206 SetErrorCode(aFail.GetMessageString());
3210 std::string aPatternStr;
3215 aPatternStr = "GEOM.SQUARE";
3218 aPatternStr = "GEOM.HEXAGON";
3222 //Make a Python command
3223 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3230 //=============================================================================
3232 * This function allows to create a disk already divided into blocks. It can be
3233 * used to create divided pipes for later meshing in hexaedra.
3234 * \param theR Radius of the disk
3235 * \param theRatio Relative size of the central square diagonal against the disk diameter
3236 * \return New GEOM_Object, containing the created shape.
3238 //=============================================================================
3239 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3240 Handle(GEOM_Object) theVec,
3248 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDDISK);
3250 //Add a new shape function with parameters
3251 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3252 if (aFunction.IsNull()) return NULL;
3254 //Check if the function is set correctly
3255 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3257 AdvancedEngine_IDividedDisk aData (aFunction);
3259 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3260 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3262 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3264 aData.SetCenter(aRefPnt);
3265 aData.SetVector(aRefVec);
3268 aData.SetRatio(theRatio);
3269 aData.SetType(thePattern);
3271 //Compute the resulting value
3274 if (!GetSolver()->ComputeFunction(aFunction)) {
3275 SetErrorCode("DividedDisk driver failed");
3279 catch (Standard_Failure& aFail) {
3280 SetErrorCode(aFail.GetMessageString());
3284 std::string aPatternStr;
3289 aPatternStr = "GEOM.SQUARE";
3292 aPatternStr = "GEOM.HEXAGON";
3297 //Make a Python command
3298 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3305 //=============================================================================
3307 * Builds a cylinder prepared for hexa meshes
3308 * \param theR Radius of the cylinder
3309 * \param theH Height of the cylinder
3310 * \return New GEOM_Object, containing the created shape.
3312 //=============================================================================
3313 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3320 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_DIVIDEDCYLINDER);
3322 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3323 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3325 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3327 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3328 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3329 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3331 std::string aPatternStr;
3336 aPatternStr = "GEOM.SQUARE";
3339 aPatternStr = "GEOM.HEXAGON";
3343 //Make a Python command
3344 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3350 //=============================================================================
3352 * Create a smoothing surface from a set of points
3353 * \param thelPoints list of points or compounds of points
3354 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3355 * \param theDegMax maximum degree of the resulting BSpline surface
3356 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3357 * \return New GEOM_Object, containing the created shape.
3359 //=============================================================================
3360 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3368 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GEOM_SMOOTHINGSURFACE);
3370 //Add a new shape function with parameters
3371 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3372 if (aFunction.IsNull()) return NULL;
3374 //Check if the function is set correctly
3375 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3377 AdvancedEngine_ISmoothingSurface aData (aFunction);
3379 int aLen = thelPoints.size();
3380 aData.SetLength(aLen);
3382 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3383 for (; it != thelPoints.end(); it++, ind++) {
3384 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3385 if (aRefObj.IsNull()) {
3386 SetErrorCode("NULL point or compound for bSplineFaceShape");
3389 aData.SetPntOrComp(ind, aRefObj);
3392 aData.SetNbMax(theNbMax);
3393 aData.SetDegMax(theDegMax);
3394 aData.SetDMax(theDMax);
3396 //Compute the resulting value
3399 if (!GetSolver()->ComputeFunction(aFunction)) {
3400 SetErrorCode("SmoothingSurface driver failed");
3404 catch (Standard_Failure& aFail) {
3405 SetErrorCode(aFail.GetMessageString());
3409 //Make a Python command
3410 GEOM::TPythonDump pd (aFunction);
3411 pd << aShape << " = geompy.MakeSmoothingSurface([";
3412 it = thelPoints.begin();
3414 while (it != thelPoints.end()) {
3415 pd << ", " << (*it++);
3419 << theDegMax << ", "