1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_ClsfSurf.hxx"
40 #include "GEOMAlgo_FinderShapeOn2.hxx"
41 #include "GEOMAlgo_Splitter.hxx"
43 #include "GEOMImpl_Gen.hxx"
44 #include "GEOMImpl_Types.hxx"
46 #include "GEOMImpl_IBasicOperations.hxx"
47 #include "GEOMImpl_IBooleanOperations.hxx"
48 #include "GEOMImpl_IShapesOperations.hxx"
49 #include "GEOMImpl_ITransformOperations.hxx"
50 #include "GEOMImpl_IBlocksOperations.hxx"
51 #include "GEOMImpl_I3DPrimOperations.hxx"
52 #include "GEOMImpl_ILocalOperations.hxx"
53 #include "GEOMImpl_IHealingOperations.hxx"
54 #include "GEOMImpl_IGroupOperations.hxx"
55 #include "GEOMImpl_GlueDriver.hxx"
57 #include <TDF_Tool.hxx>
58 #include <TFunction_DriverTable.hxx>
59 #include <TFunction_Driver.hxx>
60 #include <TFunction_Logbook.hxx>
61 #include <TNaming_CopyShape.hxx>
64 #include <TopExp_Explorer.hxx>
66 #include <TopoDS_Vertex.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <TopTools_ListIteratorOfListOfShape.hxx>
69 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
71 #include <BRep_Builder.hxx>
72 #include <BRep_Tool.hxx>
74 #include <BRepAdaptor_Surface.hxx>
75 #include <BRepAlgoAPI_Cut.hxx>
76 #include <BRepAlgoAPI_Fuse.hxx>
77 #include <BRepBuilderAPI_MakeFace.hxx>
78 #include <BRepBuilderAPI_MakeVertex.hxx>
79 #include <BRepBuilderAPI_Transform.hxx>
80 #include <BRepPrimAPI_MakeCone.hxx>
81 #include <BRepPrimAPI_MakeCylinder.hxx>
87 #include <GC_MakeConicalSurface.hxx>
88 #include <Geom_CylindricalSurface.hxx>
90 #include <ShapeAnalysis_Edge.hxx>
94 #include "AdvancedEngine_Types.hxx"
96 #include <Standard_Stream.hxx>
97 #include <Standard_Failure.hxx>
98 #include <StdFail_NotDone.hxx>
99 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
101 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
102 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
103 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
104 #define THICKNESS "Thickness" //"Epaisseur"
105 #define FLANGE "Flange" // "Collerette"
106 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
107 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
108 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
109 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
111 #define FIND_GROUPS_BY_POINTS 1
113 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
114 // VSR 30/12/2014: macro enabled
115 #define FILLET_FIX_TOLERANCE
117 //=============================================================================
121 //=============================================================================
122 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
123 GEOM_IOperations(theEngine, theDocID)
125 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
126 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
127 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
128 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
129 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
130 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
131 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
132 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
133 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
134 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
137 //=============================================================================
141 //=============================================================================
142 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
144 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
145 delete myBasicOperations;
146 delete myBooleanOperations;
147 delete myShapesOperations;
148 delete myTransformOperations;
149 delete myBlocksOperations;
150 delete my3DPrimOperations;
151 delete myLocalOperations;
152 delete myHealingOperations;
153 delete myGroupOperations;
156 //=============================================================================
160 //=============================================================================
161 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
162 Handle(GEOM_Object) theP1,
163 Handle(GEOM_Object) theP2,
164 Handle(GEOM_Object) theP3)
166 // Old Local Coordinates System oldLCS
168 gp_Pnt P1(-theL1, 0, 0);
169 gp_Pnt P2(theL1, 0, 0);
170 gp_Pnt P3(0, 0, theL2);
172 gp_Dir oldX(gp_Vec(P1, P2));
173 gp_Dir oldZ(gp_Vec(P0, P3));
174 gp_Ax3 oldLCS(P0, oldZ, oldX);
176 // New Local Coordinates System newLCS
177 double LocX, LocY, LocZ;
178 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
179 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
180 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
181 LocX = (newP1.X() + newP2.X()) / 2.;
182 LocY = (newP1.Y() + newP2.Y()) / 2.;
183 LocZ = (newP1.Z() + newP2.Z()) / 2.;
184 gp_Pnt newO(LocX, LocY, LocZ);
186 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
187 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
188 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
191 aTrsf.SetDisplacement(oldLCS, newLCS);
196 //=============================================================================
198 * CheckCompatiblePosition
201 //=============================================================================
202 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
203 Handle(GEOM_Object) theP1,
204 Handle(GEOM_Object) theP2,
205 Handle(GEOM_Object) theP3,
209 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
210 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
211 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
213 double d12 = P1.Distance(P2);
214 double d13 = P1.Distance(P3);
215 double d23 = P2.Distance(P3);
216 // double d2 = newO.Distance(P3);
218 if (Abs(d12) <= Precision::Confusion()) {
219 SetErrorCode("Junctions points P1 and P2 are identical");
222 if (Abs(d13) <= Precision::Confusion()) {
223 SetErrorCode("Junctions points P1 and P3 are identical");
226 if (Abs(d23) <= Precision::Confusion()) {
227 SetErrorCode("Junctions points P2 and P3 are identical");
232 double newL1 = 0.5 * d12;
233 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
235 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
237 if (fabs(newL1 - theL1) > Precision::Approximation()) {
238 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
239 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
240 // std::cerr << "theL1 = newL1" << std::endl;
244 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
250 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
252 if (fabs(newL2 - theL2) > Precision::Approximation()) {
253 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
254 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
258 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
268 //=============================================================================
270 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
272 //=============================================================================
273 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
274 double theR1, double theW1, double theL1,
275 double theR2, double theW2, double theL2,
276 double theH, double theW, double theRF,
277 Handle(TColStd_HSequenceOfTransient) theSeq,
282 if (theShape.IsNull()) return false;
284 TopoDS_Shape aShape = theShape->GetValue();
285 if (aShape.IsNull()) {
286 SetErrorCode("Shape is not defined");
290 gp_Trsf aTrsfInv = aTrsf.Inverted();
292 // int expectedGroups = 0;
293 // if (shapeType == TSHAPE_BASIC)
294 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
295 // expectedGroups = 10;
297 // expectedGroups = 11;
298 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
299 // expectedGroups = 12;
301 double aR1Ext = theR1 + theW1;
302 double aR2Ext = theR2 + theW2;
304 /////////////////////////
305 //// Groups of Faces ////
306 /////////////////////////
309 // Comment the following lines when GetInPlace bug is solved
311 // Workaround of GetInPlace bug
312 // Create a bounding box that fits the shape
313 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
314 aBox->GetLastFunction()->SetDescription("");
315 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
316 aBox->GetLastFunction()->SetDescription("");
317 // Apply transformation to box
318 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
319 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
320 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
322 // Get the shell of the box
323 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
324 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
325 aBox->GetLastFunction()->SetDescription("");
326 aShell->GetLastFunction()->SetDescription("");
327 // Get the common shapes between shell and shape
328 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
329 (theShape, aShell, 1, Standard_False); // MakeCommon
330 if (aCommonCompound.IsNull()) {
331 SetErrorCode(myBooleanOperations->GetErrorCode());
334 aCommonCompound->GetLastFunction()->SetDescription("");
335 // Explode the faces of common shapes => 3 faces
336 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
337 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
338 aCommonCompound->GetLastFunction()->SetDescription("");
339 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
341 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
342 std::list<Handle(GEOM_Object)> aFacesList;
343 for (int j = 1 ; j <= 4 ; j++) {
344 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
345 if (!aFace.IsNull()) {
346 aFace->GetLastFunction()->SetDescription("");
347 aFacesList.push_back(aFace);
350 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
351 if (!aCompoundOfFaces.IsNull()) {
352 aCompoundOfFaces->GetLastFunction()->SetDescription("");
353 aCompoundOfFacesList.push_back(aCompoundOfFaces);
357 if (aCompoundOfFacesList.size() == 3) {
358 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
359 aCompoundOfFacesList.pop_front();
360 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
361 aCompoundOfFacesList.pop_front();
362 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
363 aCompoundOfFacesList.pop_front();
368 // Uncomment the following lines when GetInPlace bug is solved
370 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
371 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
372 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
373 // aP1->GetLastFunction()->SetDescription("");
374 // aP2->GetLastFunction()->SetDescription("");
375 // aP3->GetLastFunction()->SetDescription("");
376 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
377 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
378 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
379 // aV1->GetLastFunction()->SetDescription("");
380 // aV2->GetLastFunction()->SetDescription("");
381 // aV3->GetLastFunction()->SetDescription("");
382 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
383 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
384 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
385 // aPln1->GetLastFunction()->SetDescription("");
386 // aPln2->GetLastFunction()->SetDescription("");
387 // aPln3->GetLastFunction()->SetDescription("");
389 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
390 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
391 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
392 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
393 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
394 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
395 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
396 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
397 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
401 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
402 if (junctionFaces1.IsNull())
403 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
404 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
405 if (!junctionFaces1.IsNull()) {
406 junctionFaces1->GetLastFunction()->SetDescription("");
407 junctionFaces1->SetName("JUNCTION_FACE_1");
408 theSeq->Append(junctionFaces1);
411 SetErrorCode("Junction face 1 not found");
412 // theSeq->Append(aPln1);
415 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
416 if (junctionFaces2.IsNull())
417 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
418 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
419 if (!junctionFaces2.IsNull()) {
420 junctionFaces2->GetLastFunction()->SetDescription("");
421 junctionFaces2->SetName("JUNCTION_FACE_2");
422 theSeq->Append(junctionFaces2);
425 SetErrorCode("Junction face 2 not found");
426 // theSeq->Append(aPln2);
429 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
430 if (junctionFaces3.IsNull())
431 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
432 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
433 if (!junctionFaces3.IsNull()) {
434 junctionFaces3->GetLastFunction()->SetDescription("");
435 junctionFaces3->SetName("JUNCTION_FACE_3");
436 theSeq->Append(junctionFaces3);
439 SetErrorCode("Junction face 3 not found");
440 // theSeq->Append(aPln3);
443 // Comment the following lines when GetInPlace bug is solved
448 /////////////////////////
449 //// Groups of Edges ////
450 /////////////////////////
451 // Result of propagate
453 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
455 TCollection_AsciiString theDesc = aFunction->GetDescription();
456 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
457 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
458 SetErrorCode("Propagation groups not found");
461 Standard_Integer aNbGroups = aSeqPropagate->Length();
462 // Recover previous description to get rid of Propagate dump
463 aFunction->SetDescription(theDesc);
465 #ifdef FIND_GROUPS_BY_POINTS
466 // BEGIN: new groups search
473 // g / ''..| | |..'' \
475 // .---.--'.. | | | ..'--.---.
476 // |a \ '''...........''' / |
477 // |-------\------' | '------/-------.
482 // ._________________|_________________.
488 // |-----------------|-----------------|
490 // '-----------------'-----------------'
493 // "Thickness" group (a)
494 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
495 aPntA.Transform(aTrsf);
496 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
497 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
498 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
500 // "Circular quarter of pipe" group (b)
501 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
502 aPntB.Transform(aTrsf);
503 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
504 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
505 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
507 // "Circular quarter of pipe" group (c)
508 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
509 aPntC.Transform(aTrsf);
510 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
511 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
512 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
514 // "Main pipe half length" group (d)
515 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
516 aPntD.Transform(aTrsf);
517 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
518 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
519 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
521 // "Incident pipe half length" group (e)
522 double aTol10 = Precision::Confusion() * 10.;
523 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
524 aPntE.Transform(aTrsf);
525 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
526 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
527 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
529 // "Flange" group (f)
530 double aFx = - aR2Ext - aTol10;
531 if (shapeType == TSHAPE_CHAMFER)
533 else if (shapeType == TSHAPE_FILLET)
535 gp_Pnt aPntF (aFx, 0, aR1Ext);
536 aPntF.Transform(aTrsf);
537 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
538 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
539 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
541 // "Chamfer or Fillet" group (g)
542 TopoDS_Shape anEdgeG;
543 if (shapeType == TSHAPE_CHAMFER) {
544 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
545 aPntG.Transform(aTrsf);
546 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
547 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
548 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
550 else if (shapeType == TSHAPE_FILLET) {
551 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
552 aPntG.Transform(aTrsf);
553 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
554 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
555 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
558 for (int i = 1 ; i <= aNbGroups; i++) {
559 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
563 TopoDS_Shape aGroupShape = aGroup->GetValue();
564 TopTools_IndexedMapOfShape anEdgesMap;
565 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
567 if (anEdgesMap.Contains(anEdgeA)) { // a
568 aGroup->SetName("THICKNESS");
569 theSeq->Append(aGroup);
571 else if (anEdgesMap.Contains(anEdgeB)) { // b
572 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
573 theSeq->Append(aGroup);
575 else if (anEdgesMap.Contains(anEdgeC)) { // c
576 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
577 theSeq->Append(aGroup);
579 else if (anEdgesMap.Contains(anEdgeD)) { // d
580 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
581 theSeq->Append(aGroup);
583 else if (anEdgesMap.Contains(anEdgeE)) { // e
584 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
585 theSeq->Append(aGroup);
587 else if (anEdgesMap.Contains(anEdgeF)) { // f
588 aGroup->SetName("FLANGE");
589 theSeq->Append(aGroup);
591 else if (shapeType == TSHAPE_CHAMFER) { // g
592 if (anEdgesMap.Contains(anEdgeG)) {
593 aGroup->SetName("CHAMFER");
594 theSeq->Append(aGroup);
597 else if (shapeType == TSHAPE_FILLET) { // g
598 if (anEdgesMap.Contains(anEdgeG)) {
599 aGroup->SetName("FILLET");
600 theSeq->Append(aGroup);
606 // END: new groups search
609 bool circularFoundAndAdded = false;
610 bool circularFound10 = false;
611 bool incidentPipeFound = false;
612 bool mainPipeFound = false;
613 bool mainPipeFoundAndAdded = false;
614 bool radialFound =false;
615 bool flangeFound = false;
616 bool flangeFoundAndAdded = false;
617 bool chamferOrFilletFound = false;
619 for (int i = 1 ; i <= aNbGroups; i++) {
622 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
626 TopoDS_Shape aGroupShape = aGroup->GetValue();
627 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
628 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
630 TopTools_IndexedMapOfShape anEdgesMap;
631 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
632 Standard_Integer nbEdges = anEdgesMap.Extent();
634 if (shapeType == TSHAPE_BASIC) {
635 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
637 aGroup->SetName("THICKNESS");
639 else if (nbEdges == 6) {
640 if (!circularFoundAndAdded) {
641 circularFoundAndAdded = true;
643 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
646 else if (nbEdges == 8) {
647 incidentPipeFound = true;
648 mainPipeFound = false;
652 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
654 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
655 double x=aP.X(), y=aP.Y(), z=aP.Z();
658 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
659 (Abs(y) > aR2Ext + Precision::Confusion())) {
660 incidentPipeFound = false;
663 if ( z < -Precision::Confusion()) {
664 // length of main pipe
665 mainPipeFound = true;
666 if (!mainPipeFoundAndAdded) {
667 mainPipeFoundAndAdded = true;
669 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
673 else if (Abs(x) > (theL1-Precision::Confusion())) {
674 // discretisation circulaire
676 if (!circularFoundAndAdded) {
677 circularFoundAndAdded = true;
679 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
684 if (incidentPipeFound) {
686 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
688 if (!addGroup && (!incidentPipeFound &&
692 // Flange (collerette)
695 aGroup->SetName("FLANGE");
701 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
702 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
704 aGroup->SetName("THICKNESS");
706 else if ((nbEdges == 10) || (nbEdges == 6)) {
707 if (!circularFoundAndAdded) {
709 circularFoundAndAdded = true;
710 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
712 circularFound10 = true;
715 else if (!circularFound10 && nbEdges == 10) {
716 circularFound10 = true;
718 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
721 else if (nbEdges == 8) {
722 incidentPipeFound = true;
723 mainPipeFound = true;
726 bool isNearZ0 = false;
727 bool isBelowZ0 = false;
729 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
731 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
732 double x=aP.X(), y=aP.Y(), z=aP.Z();
734 // tuy_princ_long_avant & tuy_princ_long_apres
735 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
736 // ((y <= aR1Ext + Precision::Confusion()) ||
737 // (y <= -(aR1Ext + Precision::Confusion())) ||
738 // (y <= theR1 + Precision::Confusion()) ||
739 // (y == -(theR1 + Precision::Confusion()))));
740 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
741 (fabs(y) > theR1 - Precision::Confusion() ||
742 fabs(y) < Precision::Confusion()));
745 mainPipeFound = false;
749 //if (z < Precision::Confusion() && !isMain) {
750 // flangeFound = true;
751 // if (!flangeFoundAndAdded) {
752 // flangeFoundAndAdded = true;
754 // aGroup->SetName("FLANGE");
757 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
758 if (z < - Precision::Confusion()) isBelowZ0 = true;
761 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
762 (Abs(y) > aR2Ext + Precision::Confusion())) {
763 incidentPipeFound = false;
769 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
771 if (incidentPipeFound) {
773 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
775 if (isNearZ0 && !isBelowZ0) {
777 if (!flangeFoundAndAdded) {
778 flangeFoundAndAdded = true;
780 aGroup->SetName("FLANGE");
783 if (!addGroup && (!incidentPipeFound &&
786 !chamferOrFilletFound)) {
788 chamferOrFilletFound = true;
789 if (shapeType == TSHAPE_CHAMFER)
790 aGroup->SetName("CHAMFER");
792 aGroup->SetName("FILLET");
798 // Add group to the list
800 theSeq->Append(aGroup);
808 //=============================================================================
810 * Return faces that are laying on surface.
812 //=============================================================================
813 bool AdvancedEngine_IOperations::GetFacesOnSurf
814 (const TopoDS_Shape &theShape,
815 const Handle_Geom_Surface& theSurface,
816 const Standard_Real theTolerance,
817 TopTools_ListOfShape &theFaces)
819 GEOMAlgo_FinderShapeOn2 aFinder;
820 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
822 aClsfSurf->SetSurface(theSurface);
823 aFinder.SetShape(theShape);
824 aFinder.SetTolerance(theTolerance);
825 aFinder.SetClsf(aClsfSurf);
826 aFinder.SetShapeType(TopAbs_FACE);
827 aFinder.SetState(GEOMAlgo_ST_ON);
829 // Sets the minimal number of inner points for the faces that do not have own
830 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
832 aFinder.SetNbPntsMin(3);
833 // Sets the maximal number of inner points for edges or faces.
834 // It is usefull for the cases when this number is very big (e.g =2000) to improve
835 // the performance. If this value =0, all inner points will be taken into account.
837 aFinder.SetNbPntsMax(100);
840 // Interprete results
841 Standard_Integer iErr = aFinder.ErrorStatus();
842 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
844 MESSAGE(" iErr : " << iErr);
845 TCollection_AsciiString aMsg (" iErr : ");
846 aMsg += TCollection_AsciiString(iErr);
850 Standard_Integer iWrn = aFinder.WarningStatus();
851 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
853 MESSAGE(" *** iWrn : " << iWrn);
856 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
857 TopTools_ListIteratorOfListOfShape anIter (aListRes);
859 for (; anIter.More(); anIter.Next()) {
860 theFaces.Append(anIter.Value());
866 //=============================================================================
868 * Creates and returns conical face.
870 //=============================================================================
871 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
872 (const gp_Ax2 &theAxis,
873 const double theRadius,
874 const double theRadiusThin,
875 const double theHeight,
876 const gp_Trsf &theTrsf)
878 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
879 TopoDS_Shape aResult;
882 if (aMkCone.IsDone()) {
883 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
885 for (; anExp.More(); anExp.Next()) {
886 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
888 if (aFace.IsNull() == Standard_False) {
889 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
891 if (anAdaptor.GetType() == GeomAbs_Cone) {
892 // This is a conical face. Transform and return it.
893 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
895 aResult = aTransf.Shape();
905 //=============================================================================
907 * Generate the internal group of a Pipe T-Shape
909 //=============================================================================
910 bool AdvancedEngine_IOperations::MakeInternalGroup
911 (const Handle(GEOM_Object) &theShape,
912 const double theR1, const double theLen1,
913 const double theR2, const double theLen2,
914 const double theRL, double theTransLenL,
915 const double theRR, double theTransLenR,
916 const double theRI, double theTransLenI,
917 const Handle(TColStd_HSequenceOfTransient) &theSeq,
918 const gp_Trsf &theTrsf)
922 if (theShape.IsNull()) {
926 TopoDS_Shape aShape = theShape->GetValue();
928 if (aShape.IsNull()) {
929 SetErrorCode("Shape is not defined");
934 Standard_Real aMaxTol = -RealLast();
935 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
937 for (; anExp.More(); anExp.Next()) {
938 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
940 if (aVertex.IsNull() == Standard_False) {
941 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
943 if (aTol > aMaxTol) {
949 // Construct internal surfaces.
950 Standard_Integer i = 0;
951 const Standard_Integer aMaxNbSurf = 5;
952 Handle(Geom_Surface) aSurface[aMaxNbSurf];
953 TopTools_ListOfShape aConicalFaces;
954 Standard_Real aTolConf = Precision::Confusion();
956 // 1. Construct the internal surface of main pipe.
957 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
958 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
962 // 2. Construct the internal surface of incident pipe.
963 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
965 // 3. Construct the internal surface of left reduction pipe.
966 if (theRL > aTolConf) {
967 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
969 if (theTransLenL > aTolConf) {
970 // 3.1. Construct the internal surface of left transition pipe.
971 gp_Pnt aPLeft (-theLen1, 0., 0.);
972 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
973 TopoDS_Shape aConeLeft =
974 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
976 if (aConeLeft.IsNull() == Standard_False) {
977 aConicalFaces.Append(aConeLeft);
982 // 4. Construct the internal surface of right reduction pipe.
983 if (theRR > aTolConf) {
984 // There is no need to construct another cylinder of the same radius. Skip it.
985 if (Abs(theRR - theRL) > aTolConf) {
986 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
989 if (theTransLenL > aTolConf) {
990 // 4.1. Construct the internal surface of right transition pipe.
991 gp_Pnt aPRight (theLen1, 0., 0.);
992 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
993 TopoDS_Shape aConeRight =
994 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
996 if (aConeRight.IsNull() == Standard_False) {
997 aConicalFaces.Append(aConeRight);
1002 // 5. Construct the internal surface of incident reduction pipe.
1003 if (theRI > aTolConf) {
1004 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1006 if (theTransLenI > aTolConf) {
1007 // 5.1. Construct the internal surface of incident transition pipe.
1008 gp_Pnt aPInci (0., 0., theLen2);
1009 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1010 TopoDS_Shape aConeInci =
1011 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1013 if (aConeInci.IsNull() == Standard_False) {
1014 aConicalFaces.Append(aConeInci);
1019 // Get faces that are laying on cylindrical surfaces.
1020 TopTools_ListOfShape aFaces;
1021 gp_Trsf anInvTrsf = theTrsf.Inverted();
1023 for (i = 0; i < aMaxNbSurf; i++) {
1024 if (aSurface[i].IsNull()) {
1028 aSurface[i]->Transform(theTrsf);
1030 TopTools_ListOfShape aLocalFaces;
1032 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1037 // Check if the result contains outer cylinders.
1038 // It is required for main and incident pipes.
1039 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1041 while (anIter.More()) {
1042 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1043 Standard_Boolean isInside = Standard_False;
1045 // Get a vertex from this shape
1047 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1049 if (aVtx.IsNull() == Standard_False) {
1050 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1052 aPnt.Transform(anInvTrsf);
1055 // Check if the point is inside the main pipe.
1056 isInside = (Abs(aPnt.X()) <= theLen1);
1058 // Check if the point is inside the incident pipe.
1059 isInside = (aPnt.Z() <= theLen2);
1068 // Remove this face.
1069 aLocalFaces.Remove(anIter);
1074 aFaces.Append(aLocalFaces);
1077 // Get faces that are laying on conical faces.
1078 if (aConicalFaces.IsEmpty() == Standard_False) {
1079 Handle(GEOM_Object) aCone =
1080 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1081 Handle(GEOM_Function) aFunction =
1082 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1083 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1084 Handle(GEOM_Object) aConeFromShape;
1086 for (; aFIter.More(); aFIter.Next()) {
1087 aFunction->SetValue(aFIter.Value());
1088 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1090 if (aConeFromShape.IsNull() == Standard_False) {
1091 aConeFromShape->GetLastFunction()->SetDescription("");
1092 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1093 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1095 for (; anExp.More(); anExp.Next()) {
1096 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1098 if (aConeFace.IsNull() == Standard_False) {
1099 aFaces.Append(aConeFace);
1106 // Create a group of internal faces.
1107 if (aFaces.IsEmpty() == Standard_False) {
1108 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1110 if (aGroup.IsNull() == Standard_False) {
1111 aGroup->GetLastFunction()->SetDescription("");
1112 aGroup->SetName("INTERNAL_FACES");
1114 TopTools_IndexedMapOfShape anIndices;
1115 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1117 TopExp::MapShapes(aShape, anIndices);
1119 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1121 for (; anIter.More(); anIter.Next()) {
1122 const TopoDS_Shape &aFace = anIter.Value();
1123 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1126 aSeqIDs->Append(anIndex);
1130 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1131 aGroup->GetLastFunction()->SetDescription("");
1132 theSeq->Append(aGroup);
1141 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1142 double theR1, double theW1, double theL1,
1143 double theR2, double theW2, double theL2,
1144 double theH, double theW,
1145 double theRF, bool isNormal)
1149 // Build tools for partition operation:
1150 // 1 face and 2 planes
1152 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1153 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1154 Handle(GEOM_Object) chan_racc;
1155 Handle(GEOM_Object) vi1, vi2;
1156 Handle(GEOM_Object) Te3;
1160 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1161 Vector_Z->GetLastFunction()->SetDescription("");
1164 double aSize = 2*(theL1 + theL2);
1165 double aR1Ext = theR1 + theW1;
1166 double aR2Ext = theR2 + theW2;
1167 double theVertCylinderRadius = aR2Ext + theW + theRF;
1168 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1170 // Common edges on internal cylinder
1171 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1172 box_i->GetLastFunction()->SetDescription("");
1173 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1174 box_i->GetLastFunction()->SetDescription("");
1176 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1177 TCollection_AsciiString theDesc = aFunction->GetDescription();
1178 Handle(TColStd_HSequenceOfTransient) edges_i =
1179 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1180 // Recover previous description to get rid of Propagate dump
1181 aFunction->SetDescription(theDesc);
1182 if (edges_i.IsNull() || edges_i->Length() == 0) {
1183 SetErrorCode("Internal edges not found");
1186 for (int i=1; i<=edges_i->Length();i++) {
1187 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1188 anObj->GetLastFunction()->SetDescription("");
1190 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1192 // search for vertices located on both internal pipes
1193 aFunction = theShape->GetLastFunction();
1194 theDesc = aFunction->GetDescription();
1195 Handle(TColStd_HSequenceOfTransient) vertices_i =
1196 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1197 // Recover previous description to get rid of Propagate dump
1198 aFunction->SetDescription(theDesc);
1199 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1200 SetErrorCode("Internal vertices not found");
1204 double d1min = theR2+theW2, d2min=theR2+theW2;
1205 for (int i = 1; i <= vertices_i->Length(); i++) {
1206 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1207 v->GetLastFunction()->SetDescription("");
1208 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1209 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1210 if (Abs(aP.X()) <= Precision::Confusion()) {
1211 if (Abs(aP.Y()) < d1min) {
1213 d1min = Abs(aP.Y());
1215 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1216 if (Abs(aP.X()) < d2min) {
1218 d2min = Abs(aP.X());
1222 if (vi1.IsNull() || vi2.IsNull()) {
1223 SetErrorCode("Cannot find internal intersection vertices");
1227 std::list<Handle(GEOM_Object)> theShapes;
1230 Handle(GEOM_Object) ve1, ve2;
1231 TopoDS_Vertex vertex1, vertex2;
1233 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1234 box_e->GetLastFunction()->SetDescription("");
1235 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1236 box_e->GetLastFunction()->SetDescription("");
1238 // search for vertices located on both external pipes
1239 aFunction = theShape->GetLastFunction();
1240 theDesc = aFunction->GetDescription();
1241 Handle(TColStd_HSequenceOfTransient) vertices_e =
1242 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1243 // Recover previous description to get rid of Propagate dump
1244 aFunction->SetDescription(theDesc);
1245 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1246 SetErrorCode("External vertices not found");
1250 double d1max = 0, d2max = 0;
1251 for (int i = 1; i <= vertices_e->Length(); i++) {
1252 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1253 v->GetLastFunction()->SetDescription("");
1254 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1255 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1256 if (Abs(aP.X()) <= Precision::Confusion()) {
1257 if (Abs(aP.Y()) > d1max) {
1260 d1max = Abs(aP.Y());
1262 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1263 if (Abs(aP.X()) > d2max) {
1266 d2max = Abs(aP.X());
1270 if (ve1.IsNull() || ve2.IsNull()) {
1271 SetErrorCode("Cannot find external intersection vertices");
1274 Handle(GEOM_Object) edge_e1, edge_e2;
1276 // Common edges on external cylinder
1277 aFunction = theShape->GetLastFunction();
1278 theDesc = aFunction->GetDescription();
1279 Handle(TColStd_HSequenceOfTransient) edges_e =
1280 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1281 // Recover previous description to get rid of Propagate dump
1282 aFunction->SetDescription(theDesc);
1283 if (edges_e.IsNull() || edges_e->Length() == 0) {
1284 SetErrorCode("External edges not found");
1287 ShapeAnalysis_Edge sae;
1288 for (int i=1; i<=edges_e->Length();i++) {
1289 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1290 anObj->GetLastFunction()->SetDescription("");
1291 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1292 if ( !anEdge.IsNull() &&
1293 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1294 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1295 arete_intersect_ext = anObj;
1299 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1300 if (edge_e1.IsNull()) {
1301 SetErrorCode("Edge 1 could not be built");
1305 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1306 if (edge_e2.IsNull()) {
1307 SetErrorCode("Edge 2 could not be built");
1311 edge_e1->GetLastFunction()->SetDescription("");
1312 edge_e2->GetLastFunction()->SetDescription("");
1314 std::list<Handle(GEOM_Object)> edge_e_elist;
1315 edge_e_elist.push_back(arete_intersect_int);
1316 edge_e_elist.push_back(edge_e1);
1317 edge_e_elist.push_back(arete_intersect_ext);
1318 edge_e_elist.push_back(edge_e2);
1319 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1320 if (wire_t.IsNull()) {
1321 SetErrorCode("Impossible to build wire");
1324 wire_t->GetLastFunction()->SetDescription("");
1325 face_t = myShapesOperations->MakeFace(wire_t, false);
1326 if (face_t.IsNull()) {
1327 SetErrorCode("Impossible to build face");
1330 face_t->GetLastFunction()->SetDescription("");
1332 theShapes.push_back(theShape);
1333 theShapes.push_back(vi1);
1334 theShapes.push_back(vi2);
1335 theShapes.push_back(ve1);
1336 theShapes.push_back(ve2);
1337 theShapes.push_back(edge_e1);
1338 theShapes.push_back(edge_e2);
1339 theShapes.push_back(wire_t);
1340 theShapes.push_back(face_t);
1343 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1344 int idP1, idP2, idP3, idP4;
1347 std::vector<int> LX;
1348 std::vector<int> LY;
1349 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1350 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1351 box_e->GetLastFunction()->SetDescription("");
1352 box_e = myTransformOperations->TranslateDXDYDZ
1353 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1354 box_e->GetLastFunction()->SetDescription("");
1356 aFunction = theShape->GetLastFunction();
1357 theDesc = aFunction->GetDescription();
1358 Handle(TColStd_HSequenceOfTransient) extremVertices =
1359 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1360 // Recover previous description to get rid of Propagate dump
1361 aFunction->SetDescription(theDesc);
1363 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1365 SetErrorCode("Vertices on chamfer not found");
1367 SetErrorCode("Vertices on fillet not found");
1371 theShapes.push_back(theShape);
1372 theShapes.push_back(box_e);
1373 if (extremVertices->Length() != 6) {
1374 // for (int i=1; i<=extremVertices->Length(); i++){
1375 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1377 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1378 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1379 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1380 SetErrorCode("Bad number of vertices on chamfer found");
1384 for (int i=1; i<=extremVertices->Length(); i++){
1385 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1386 aV->GetLastFunction()->SetDescription("");
1387 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1389 if (Abs(aP.X()) <= Precision::Confusion()) {
1390 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1392 if (aP.Z()-ZX > Precision::Confusion()) {
1399 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1401 if (aP.Z() - ZY > Precision::Confusion()) {
1412 if (LX.at(0) == PZX)
1415 if (LY.at(0) == PZY)
1418 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1419 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1420 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1421 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1423 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1424 if (Cote_1.IsNull()) {
1425 SetErrorCode("Impossible to build edge in thickness");
1428 Cote_1->GetLastFunction()->SetDescription("");
1430 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1431 if (Cote_2.IsNull()) {
1432 SetErrorCode("Impossible to build edge in thickness");
1435 Cote_2->GetLastFunction()->SetDescription("");
1437 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1438 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1439 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1440 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1441 if (edge_chan_princ.IsNull()) {
1442 SetErrorCode("Impossible to find edge on main pipe");
1445 edge_chan_princ->GetLastFunction()->SetDescription("");
1447 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1448 if (edge_chan_inc.IsNull()) {
1449 SetErrorCode("Impossible to find edge on incident pipe");
1452 edge_chan_inc->GetLastFunction()->SetDescription("");
1454 std::list<Handle(GEOM_Object)> edgeList1;
1455 edgeList1.push_back(edge_chan_princ);
1456 edgeList1.push_back(Cote_1);
1457 edgeList1.push_back(arete_intersect_int);
1458 edgeList1.push_back(Cote_2);
1460 // std::cerr << "Creating wire 1" << std::endl;
1461 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1462 if (wire_t.IsNull()) {
1463 SetErrorCode("Impossible to build wire");
1466 wire_t->GetLastFunction()->SetDescription("");
1468 // std::cerr << "Creating face 1" << std::endl;
1469 face_t = myShapesOperations->MakeFace(wire_t, false);
1470 if (face_t.IsNull()) {
1471 SetErrorCode("Impossible to build face");
1474 face_t->GetLastFunction()->SetDescription("");
1475 theShapes.push_back(face_t);
1477 // Create a prism from edge_chan_inc
1478 Handle(GEOM_Object) aPrismDir = myBasicOperations->MakeVectorDXDYDZ(1., 1., 0.);
1480 if (aPrismDir.IsNull()) {
1481 SetErrorCode("Impossible to build Prism direction");
1484 aPrismDir->GetLastFunction()->SetDescription("");
1485 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, aPrismDir, theR2 + theW2);
1487 if (face_t2.IsNull()) {
1488 SetErrorCode("Impossible to build face");
1491 face_t2->GetLastFunction()->SetDescription("");
1492 theShapes.push_back(face_t2);
1496 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1497 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1498 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1499 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1500 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1501 aP0->GetLastFunction()->SetDescription("");
1502 aVZ->GetLastFunction()->SetDescription("");
1503 aVXZ->GetLastFunction()->SetDescription("");
1504 aPlnOZ->GetLastFunction()->SetDescription("");
1505 aPlnOXZ->GetLastFunction()->SetDescription("");
1506 theShapes.push_back(aPlnOZ);
1507 theShapes.push_back(aPlnOXZ);
1510 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1511 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1512 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1513 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1514 Handle(TColStd_HArray1OfInteger) theMaterials;
1516 partitionShapes->Append(theShape);
1517 theTools->Append(aPlnOZ);
1518 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1519 theTools->Append(aPlnOXZ);
1520 theTools->Append(face_t);
1522 theTools->Append(face_t2);
1524 Te3 = myBooleanOperations->MakePartition
1525 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1526 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1528 SetErrorCode("Impossible to build partition of TShape");
1531 Te3->GetLastFunction()->SetDescription("");
1533 // Last verification: result should be a block
1534 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1535 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1536 SetErrorCode("TShape is not a compound of block");
1540 // // BEGIN Compound of created shapes - Only for debug purpose
1541 // theShapes.clear();
1542 // theShapes.push_back(theShape);
1543 // theShapes.push_back(aPlnOZ);
1544 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1545 // theShapes.push_back(aPlnOXZ);
1546 // theShapes.push_back(face_t);
1548 // theShapes.push_back(face_t2);
1550 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1551 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1552 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1553 // // END Compound of created shapes - Only for debug purpose
1555 TopoDS_Shape aShape = Te3->GetValue();
1556 theShape->GetLastFunction()->SetValue(aShape);
1558 catch (Standard_Failure) {
1559 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1560 SetErrorCode(aFail->GetMessageString());
1568 // Mirror and glue faces
1569 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1570 double theR1, double theW1, double theL1,
1571 double theR2, double theW2, double theL2)
1576 double aSize = 2*(theL1 + theL2);
1577 double aR1Ext = theR1 + theW1;
1580 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1581 aP0->GetLastFunction()->SetDescription("");
1582 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1583 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1584 aVX->GetLastFunction()->SetDescription("");
1585 aVY->GetLastFunction()->SetDescription("");
1586 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1587 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1588 aPlane_OX->GetLastFunction()->SetDescription("");
1589 aPlane_OY->GetLastFunction()->SetDescription("");
1591 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1593 SetErrorCode("Impossible to build mirror of quarter TShape");
1597 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1599 SetErrorCode("Impossible to build mirror of half TShape");
1603 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1605 SetErrorCode("Impossible to build mirror of half TShape");
1609 std::list<Handle(GEOM_Object)> aShapesList;
1610 aShapesList.push_back(theShape);
1611 aShapesList.push_back(Te4);
1612 aShapesList.push_back(Te5);
1613 aShapesList.push_back(Te6);
1614 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1616 SetErrorCode("Impossible to build compound");
1620 // Copy source shape
1621 TopoDS_Shape aShapeCopy;
1622 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1623 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1625 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1626 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1628 SetErrorCode("Impossible to glue faces of TShape");
1632 TopoDS_Shape aShape = Te8->GetValue();
1633 BRepCheck_Analyzer anAna (aShape, Standard_True);
1635 if (!anAna.IsValid()) {
1636 // Try to do gluing with the tolerance equal to maximal
1637 // tolerance of vertices of the source shape.
1638 Standard_Real aTolMax = -RealLast();
1640 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1641 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1642 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1644 if (aTol > aTolMax) {
1650 Te7->GetLastFunction()->SetValue(aShapeCopy);
1651 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1654 SetErrorCode("Impossible to glue faces of TShape");
1658 aShape = Te8->GetValue();
1662 theShape->GetLastFunction()->SetValue(aShape);
1664 Te4->GetLastFunction()->SetDescription("");
1665 Te5->GetLastFunction()->SetDescription("");
1666 Te6->GetLastFunction()->SetDescription("");
1667 Te7->GetLastFunction()->SetDescription("");
1668 Te8->GetLastFunction()->SetDescription("");
1674 //=======================================================================
1675 //function : MakePipeTShapeThicknessReduction
1676 //purpose : Static method. Add thiskness reduction elements at the three
1677 // open ends of the T-Shape.
1678 //=======================================================================
1679 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1680 (TopoDS_Shape theShape,
1681 double r1, double w1, double l1,
1682 double r2, double w2, double l2,
1683 double rL, double wL, double ltransL, double lthinL,
1684 double rR, double wR, double ltransR, double lthinR,
1685 double rI, double wI, double ltransI, double lthinI,
1686 bool fuseReductions)
1688 // Add thickness reduction elements
1689 // at the three extremities: Left, Right and Incident
1691 // ---------------------.
1693 // ---------------------. \
1694 // ^ \ '-----------------.
1696 // | '-----------------'
1698 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1701 TopoDS_Shape aResult = theShape;
1702 double aTol = Precision::Confusion();
1704 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1706 // Left reduction (rL, wL, ltransL, lthinL)
1707 if (rL > aTol && wL > aTol && ltransL > aTol) {
1708 gp_Pnt aPLeft (-l1, 0, 0);
1709 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1710 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1711 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1713 if (fuseReductions) {
1714 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1715 if (!fuseL.IsDone())
1716 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1717 aResult = fuseL.Shape();
1724 B.Add(C, aReductionLeft);
1730 if (rR > aTol && wR > aTol && ltransR > aTol) {
1731 gp_Pnt aPRight (l1, 0, 0);
1732 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1733 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1734 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1736 if (fuseReductions) {
1737 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1738 if (!fuseR.IsDone())
1739 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1740 aResult = fuseR.Shape();
1747 B.Add(C, aReductionRight);
1752 // Incident reduction
1753 if (rI > aTol && wI > aTol && ltransI > aTol) {
1754 gp_Pnt aPInci (0, 0, l2);
1755 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1756 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1757 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1759 if (fuseReductions) {
1760 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1761 if (!fuseInci.IsDone())
1762 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1763 aResult = fuseInci.Shape();
1770 B.Add(C, aReductionInci);
1775 // Get rid of extra compounds
1776 TopTools_ListOfShape listShapeRes;
1777 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1778 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1780 if (!fuseReductions && listShapeRes.Extent() > 1) {
1781 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1786 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1787 for (; itSub.More(); itSub.Next())
1788 B.Add(C, itSub.Value());
1791 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1797 //=======================================================================
1798 //function : MakeThicknessReduction
1799 //purpose : Static method. Create one thickness reduction element.
1800 //=======================================================================
1801 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1802 const double R, const double W,
1803 const double Rthin, const double Wthin,
1804 const double Ltrans, const double Lthin,
1807 double aTol = Precision::Confusion();
1808 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1809 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1811 bool isThinPart = (Lthin > aTol);
1816 // ^ \ '-----------------.
1818 // | '-----------------'
1820 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1823 double RExt = R + W;
1824 double RthinExt = Rthin + Wthin;
1826 gp_Dir aNormal = theAxes.Direction();
1827 gp_Dir anXDir = theAxes.XDirection();
1828 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1829 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1831 // Build the transition part
1832 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1833 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1836 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1837 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1838 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1840 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1841 TopoDS_Shape aReduction = cut1.Shape();
1843 // Build the thin part, if required
1844 TopoDS_Shape aThinPart;
1846 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1847 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1850 if (!CExt.IsDone() || !CInt.IsDone())
1851 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1852 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1854 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1855 aThinPart = cut2.Shape();
1861 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1862 if (!fuse1.IsDone())
1863 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1864 aReduction = fuse1.Shape();
1868 // Partition the reduction on blocks
1869 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1870 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1871 gp_Pln aPln1 (anAxesPln1);
1872 gp_Pln aPln2 (anAxesPln2);
1873 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1874 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1875 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1877 GEOMAlgo_Splitter PS;
1878 PS.AddArgument(aReduction);
1880 PS.AddArgument(aThinPart);
1883 PS.SetLimit(TopAbs_SOLID);
1886 aReduction = PS.Shape();
1892 //=============================================================================
1895 * \brief Create a T-shape object with specified caracteristics for the main and
1896 * the incident pipes (radius, width, half-length).
1897 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1898 * \param theR1 Internal radius of main pipe
1899 * \param theW1 Width of main pipe
1900 * \param theL1 Half-length of main pipe
1901 * \param theR2 Internal radius of incident pipe (R2 < R1)
1902 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1903 * \param theL2 Half-length of incident pipe
1904 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1905 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1907 //=============================================================================
1908 Handle(TColStd_HSequenceOfTransient)
1909 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1910 double theR2, double theW2, double theL2,
1911 double theRL, double theWL, double theLtransL, double theLthinL,
1912 double theRR, double theWR, double theLtransR, double theLthinR,
1913 double theRI, double theWI, double theLtransI, double theLthinI,
1916 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1919 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1921 //Add a new shape function with parameters
1922 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1923 if (aFunction.IsNull()) return NULL;
1925 //Check if the function is set correctly
1926 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1928 AdvancedEngine_IPipeTShape aData (aFunction);
1936 aData.SetHexMesh(theHexMesh);
1938 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1939 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1940 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1942 //Compute the resulting value
1945 if (!GetSolver()->ComputeFunction(aFunction)) {
1946 SetErrorCode("TShape driver failed");
1951 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1953 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1957 if (isTRL || isTRR || isTRI) {
1958 // Add thickness reduction elements
1959 // at the three extremities: Left, Right and Incident
1960 TopoDS_Shape aResShape =
1961 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1962 theRL, theWL, theLtransL, theLthinL,
1963 theRR, theWR, theLtransR, theLthinR,
1964 theRI, theWI, theLtransI, theLthinI,
1966 aFunction->SetValue(aResShape);
1969 catch (Standard_Failure) {
1970 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1971 SetErrorCode(aFail->GetMessageString());
1975 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1976 aSeq->Append(aShape);
1981 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1982 0., 0., 0., aSeq, gp_Trsf()))
1986 // Get internal group.
1987 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
1988 theRR, theLtransR, theRI, theLtransI,
1993 catch (Standard_Failure) {
1994 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1995 SetErrorCode(aFail->GetMessageString());
1999 //Make a Python command
2000 TCollection_AsciiString anEntry, aListRes("[");
2001 // Iterate over the sequence aSeq
2002 Standard_Integer aNbGroups = aSeq->Length();
2003 Standard_Integer i = 1;
2004 for (; i <= aNbGroups; i++) {
2005 Handle(Standard_Transient) anItem = aSeq->Value(i);
2006 if (anItem.IsNull()) continue;
2007 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2008 if (aGroup.IsNull()) continue;
2009 //Make a Python command
2010 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2011 aListRes += anEntry + ", ";
2013 aListRes.Trunc(aListRes.Length() - 2);
2015 GEOM::TPythonDump pd (aFunction);
2017 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2018 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2019 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2022 // thickness reduction
2024 pd << ", theRL=" << theRL << ", theWL=" << theWL
2025 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2027 pd << ", theRR=" << theRR << ", theWR=" << theWR
2028 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2030 pd << ", theRI=" << theRI << ", theWI=" << theWI
2031 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2040 //=============================================================================
2042 * MakePipeTShapeWithPosition
2043 * Create a T-shape object with specified caracteristics for the main and
2044 * the incident pipes (radius, width, half-length).
2045 * The extremities of the main pipe are located on junctions points P1 and P2.
2046 * The extremity of the incident pipe is located on junction point P3.
2047 * \param theR1 Internal radius of main pipe
2048 * \param theW1 Width of main pipe
2049 * \param theL1 Half-length of main pipe
2050 * \param theR2 Internal radius of incident pipe (R2 < R1)
2051 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2052 * \param theL2 Half-length of incident pipe
2053 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2054 * \param theP1 1st junction point of main pipe
2055 * \param theP2 2nd junction point of main pipe
2056 * \param theP3 Junction point of incident pipe
2057 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2059 //=============================================================================
2060 Handle(TColStd_HSequenceOfTransient)
2061 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2062 (double theR1, double theW1, double theL1,
2063 double theR2, double theW2, double theL2,
2064 double theRL, double theWL, double theLtransL, double theLthinL,
2065 double theRR, double theWR, double theLtransR, double theLthinR,
2066 double theRI, double theWI, double theLtransI, double theLthinI,
2068 Handle(GEOM_Object) theP1,
2069 Handle(GEOM_Object) theP2,
2070 Handle(GEOM_Object) theP3)
2074 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2078 //Add a new shape function with parameters
2079 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2080 if (aFunction.IsNull()) return NULL;
2082 //Check if the function is set correctly
2083 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2085 // Check new position
2086 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2090 AdvancedEngine_IPipeTShape aData(aFunction);
2098 aData.SetHexMesh(theHexMesh);
2100 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2101 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2102 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2104 //Compute the resulting value
2107 if (!GetSolver()->ComputeFunction(aFunction)) {
2108 SetErrorCode("TShape driver failed");
2113 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2115 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2119 if (isTRL || isTRR || isTRI) {
2120 // Add thickness reduction elements
2121 // at the three extremities: Left, Right and Incident
2122 TopoDS_Shape aResShape =
2123 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2124 theRL, theWL, theLtransL, theLthinL,
2125 theRR, theWR, theLtransR, theLthinR,
2126 theRI, theWI, theLtransI, theLthinI,
2128 aFunction->SetValue(aResShape);
2131 catch (Standard_Failure) {
2132 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2133 SetErrorCode(aFail->GetMessageString());
2137 TopoDS_Shape Te = aShape->GetValue();
2140 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2141 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2142 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2143 aFunction->SetValue(aTrsf_Shape);
2145 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2146 aSeq->Append(aShape);
2151 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2152 0., 0., 0., aSeq, aTrsf)) {
2157 // Get internal group.
2158 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2159 theRR, theLtransR, theRI, theLtransI,
2164 catch (Standard_Failure) {
2165 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2166 SetErrorCode(aFail->GetMessageString());
2170 //Make a Python command
2171 TCollection_AsciiString anEntry, aListRes("[");
2172 // Iterate over the sequence aSeq
2173 Standard_Integer aNbGroups = aSeq->Length();
2174 Standard_Integer i = 1;
2175 for (; i <= aNbGroups; i++) {
2176 Handle(Standard_Transient) anItem = aSeq->Value(i);
2177 if (anItem.IsNull()) continue;
2178 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2179 if (aGroup.IsNull()) continue;
2180 //Make a Python command
2181 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2182 aListRes += anEntry + ", ";
2184 aListRes.Trunc(aListRes.Length() - 2);
2186 GEOM::TPythonDump pd (aFunction);
2188 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2189 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2190 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2191 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2193 // thickness reduction
2195 pd << ", theRL=" << theRL << ", theWL=" << theWL
2196 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2198 pd << ", theRR=" << theRR << ", theWR=" << theWR
2199 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2201 pd << ", theRI=" << theRI << ", theWI=" << theWI
2202 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2211 //=============================================================================
2213 * MakePipeTShapeChamfer
2214 * Create a T-shape object with specified caracteristics for the main and
2215 * the incident pipes (radius, width, half-length). A chamfer is created
2216 * on the junction of the pipes.
2217 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2218 * \param theR1 Internal radius of main pipe
2219 * \param theW1 Width of main pipe
2220 * \param theL1 Half-length of main pipe
2221 * \param theR2 Internal radius of incident pipe (R2 < R1)
2222 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2223 * \param theL2 Half-length of incident pipe
2224 * \param theH Height of chamfer.
2225 * \param theW Width of chamfer.
2226 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2227 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2229 //=============================================================================
2230 Handle(TColStd_HSequenceOfTransient)
2231 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2232 (double theR1, double theW1, double theL1,
2233 double theR2, double theW2, double theL2,
2234 double theRL, double theWL, double theLtransL, double theLthinL,
2235 double theRR, double theWR, double theLtransR, double theLthinR,
2236 double theRI, double theWI, double theLtransI, double theLthinI,
2237 double theH, double theW,
2242 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2243 //Add a new shape function with parameters
2244 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2245 if (aFunction.IsNull()) return NULL;
2247 //Check if the function is set correctly
2248 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2250 AdvancedEngine_IPipeTShape aData(aFunction);
2260 aData.SetHexMesh(theHexMesh);
2262 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2263 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2264 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2266 //Compute the resulting value
2269 if (!GetSolver()->ComputeFunction(aFunction)) {
2270 SetErrorCode("TShape driver failed");
2274 catch (Standard_Failure) {
2275 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2276 SetErrorCode(aFail->GetMessageString());
2281 TopoDS_Shape aShapeShape = aShape->GetValue();
2282 TopTools_IndexedMapOfShape anEdgesIndices;
2283 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2284 // Common edges on external cylinders
2285 Handle(GEOM_Object) box_e;
2287 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2290 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2292 box_e->GetLastFunction()->SetDescription("");
2293 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2294 box_e->GetLastFunction()->SetDescription("");
2296 Handle(TColStd_HSequenceOfInteger) edges_e =
2297 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2298 box_e->GetLastFunction()->SetDescription("");
2300 if (edges_e.IsNull() || edges_e->Length() == 0) {
2301 SetErrorCode("External edges not found");
2304 int nbEdgesInChamfer = 0;
2305 std::list<int> theEdges;
2306 for (int i=1; i<=edges_e->Length();i++) {
2307 int edgeID = edges_e->Value(i);
2308 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2309 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2313 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2314 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2315 nbEdgesInChamfer ++;
2316 theEdges.push_back(edgeID);
2320 if (theHexMesh && nbEdgesInChamfer == 1)
2323 Handle(GEOM_Object) aChamfer;
2325 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2327 catch (Standard_Failure) {
2328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2329 SetErrorCode(aFail->GetMessageString());
2332 if (aChamfer.IsNull()) {
2333 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2336 aChamfer->GetLastFunction()->SetDescription("");
2338 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2339 aFunction->SetValue(aChamferShape);
2343 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2345 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2349 // Add thickness reduction elements
2350 // at the three extremities: Left, Right and Incident
2353 if (isTRL || isTRR || isTRI) {
2354 TopoDS_Shape aResShape =
2355 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2356 theRL, theWL, theLtransL, theLthinL,
2357 theRR, theWR, theLtransR, theLthinR,
2358 theRI, theWI, theLtransI, theLthinI,
2360 aFunction->SetValue(aResShape);
2363 catch (Standard_Failure) {
2364 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2365 SetErrorCode(aFail->GetMessageString());
2369 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2370 aSeq->Append(aShape);
2375 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2376 theH, theW, 0., aSeq, gp_Trsf()))
2380 // Get internal group.
2381 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2382 theRR, theLtransR, theRI, theLtransI,
2387 catch (Standard_Failure) {
2388 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2389 SetErrorCode(aFail->GetMessageString());
2393 //Make a Python command
2394 TCollection_AsciiString anEntry, aListRes("[");
2395 // Iterate over the sequence aSeq
2396 Standard_Integer aNbGroups = aSeq->Length();
2397 Standard_Integer i = 1;
2398 for (; i <= aNbGroups; i++) {
2399 Handle(Standard_Transient) anItem = aSeq->Value(i);
2400 if (anItem.IsNull()) continue;
2401 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2402 if (aGroup.IsNull()) continue;
2403 //Make a Python command
2404 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2405 aListRes += anEntry + ", ";
2407 aListRes.Trunc(aListRes.Length() - 2);
2409 GEOM::TPythonDump pd (aFunction);
2411 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2412 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2413 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2414 << theH << ", " << theW << ", " << theHexMesh;
2416 // thickness reduction
2418 pd << ", theRL=" << theRL << ", theWL=" << theWL
2419 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2421 pd << ", theRR=" << theRR << ", theWR=" << theWR
2422 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2424 pd << ", theRI=" << theRI << ", theWI=" << theWI
2425 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2434 //=============================================================================
2436 * MakePipeTShapeChamferWithPosition
2437 * Create a T-shape object with specified caracteristics for the main and
2438 * the incident pipes (radius, width, half-length). A chamfer is created
2439 * on the junction of the pipes.
2440 * The extremities of the main pipe are located on junctions points P1 and P2.
2441 * The extremity of the incident pipe is located on junction point P3.
2442 * \param theR1 Internal radius of main pipe
2443 * \param theW1 Width of main pipe
2444 * \param theL1 Half-length of main pipe
2445 * \param theR2 Internal radius of incident pipe (R2 < R1)
2446 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2447 * \param theL2 Half-length of incident pipe
2448 * \param theH Height of chamfer.
2449 * \param theW Width of chamfer.
2450 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2451 * \param theP1 1st junction point of main pipe
2452 * \param theP2 2nd junction point of main pipe
2453 * \param theP3 Junction point of incident pipe
2454 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2456 //=============================================================================
2457 Handle(TColStd_HSequenceOfTransient)
2458 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2459 (double theR1, double theW1, double theL1,
2460 double theR2, double theW2, double theL2,
2461 double theRL, double theWL, double theLtransL, double theLthinL,
2462 double theRR, double theWR, double theLtransR, double theLthinR,
2463 double theRI, double theWI, double theLtransI, double theLthinI,
2464 double theH, double theW,
2466 Handle(GEOM_Object) theP1,
2467 Handle(GEOM_Object) theP2,
2468 Handle(GEOM_Object) theP3)
2472 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2473 //Add a new shape function with parameters
2474 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2475 if (aFunction.IsNull()) return NULL;
2477 //Check if the function is set correctly
2478 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2480 // Check new position
2481 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2485 AdvancedEngine_IPipeTShape aData(aFunction);
2495 aData.SetHexMesh(theHexMesh);
2497 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2498 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2499 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2501 //Compute the resulting value
2504 if (!GetSolver()->ComputeFunction(aFunction)) {
2505 SetErrorCode("TShape driver failed");
2509 catch (Standard_Failure) {
2510 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2511 SetErrorCode(aFail->GetMessageString());
2516 TopoDS_Shape aShapeShape = aShape->GetValue();
2517 TopTools_IndexedMapOfShape anEdgesIndices;
2518 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2519 // Common edges on external cylinders
2520 Handle(GEOM_Object) box_e;
2522 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2525 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2527 box_e->GetLastFunction()->SetDescription("");
2528 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2529 box_e->GetLastFunction()->SetDescription("");
2531 Handle(TColStd_HSequenceOfInteger) edges_e =
2532 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2533 box_e->GetLastFunction()->SetDescription("");
2535 if (edges_e.IsNull() || edges_e->Length() == 0) {
2536 SetErrorCode("External edges not found");
2539 int nbEdgesInChamfer = 0;
2540 std::list<int> theEdges;
2541 for (int i=1; i<=edges_e->Length();i++) {
2542 int edgeID = edges_e->Value(i);
2543 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2544 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2546 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2547 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2548 nbEdgesInChamfer ++;
2549 theEdges.push_back(edgeID);
2553 if (theHexMesh && nbEdgesInChamfer == 1)
2556 Handle(GEOM_Object) aChamfer;
2558 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2560 catch (Standard_Failure) {
2561 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2562 SetErrorCode(aFail->GetMessageString());
2565 if (aChamfer.IsNull()) {
2566 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2569 aChamfer->GetLastFunction()->SetDescription("");
2571 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2572 aFunction->SetValue(aChamferShape);
2576 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2578 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2582 // Add thickness reduction elements
2583 // at the three extremities: Left, Right and Incident
2586 if (isTRL || isTRR || isTRI) {
2587 TopoDS_Shape aResShape =
2588 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2589 theRL, theWL, theLtransL, theLthinL,
2590 theRR, theWR, theLtransR, theLthinR,
2591 theRI, theWI, theLtransI, theLthinI,
2593 aFunction->SetValue(aResShape);
2596 catch (Standard_Failure) {
2597 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2598 SetErrorCode(aFail->GetMessageString());
2603 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2604 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2605 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2606 aFunction->SetValue(aTrsf_Shape);
2608 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2609 aSeq->Append(aShape);
2614 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2615 theH, theW, 0., aSeq, aTrsf))
2619 // Get internal group.
2620 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2621 theRR, theLtransR, theRI, theLtransI,
2626 catch (Standard_Failure) {
2627 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2628 SetErrorCode(aFail->GetMessageString());
2632 //Make a Python command
2633 TCollection_AsciiString anEntry, aListRes("[");
2634 // Iterate over the sequence aSeq
2635 Standard_Integer aNbGroups = aSeq->Length();
2636 Standard_Integer i = 1;
2637 for (; i <= aNbGroups; i++) {
2638 Handle(Standard_Transient) anItem = aSeq->Value(i);
2639 if (anItem.IsNull()) continue;
2640 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2641 if (aGroup.IsNull()) continue;
2642 //Make a Python command
2643 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2644 aListRes += anEntry + ", ";
2646 aListRes.Trunc(aListRes.Length() - 2);
2648 GEOM::TPythonDump pd (aFunction);
2650 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2651 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2652 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2653 << theH << ", " << theW << ", " << theHexMesh << ", "
2654 << theP1 << ", " << theP2 << ", " << theP3;
2656 // thickness reduction
2658 pd << ", theRL=" << theRL << ", theWL=" << theWL
2659 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2661 pd << ", theRR=" << theRR << ", theWR=" << theWR
2662 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2664 pd << ", theRI=" << theRI << ", theWI=" << theWI
2665 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2674 //=============================================================================
2676 * MakePipeTShapeFillet
2677 * Create a T-shape object with specified caracteristics for the main and
2678 * the incident pipes (radius, width, half-length). A fillet is created
2679 * on the junction of the pipes.
2680 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2681 * \param theR1 Internal radius of main pipe
2682 * \param theW1 Width of main pipe
2683 * \param theL1 Half-length of main pipe
2684 * \param theR2 Internal radius of incident pipe (R2 < R1)
2685 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2686 * \param theL2 Half-length of incident pipe
2687 * \param theRF Radius of curvature of fillet.
2688 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2689 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2691 //=============================================================================
2692 Handle(TColStd_HSequenceOfTransient)
2693 AdvancedEngine_IOperations::MakePipeTShapeFillet
2694 (double theR1, double theW1, double theL1,
2695 double theR2, double theW2, double theL2,
2696 double theRL, double theWL, double theLtransL, double theLthinL,
2697 double theRR, double theWR, double theLtransR, double theLthinR,
2698 double theRI, double theWI, double theLtransI, double theLthinI,
2699 double theRF, bool theHexMesh)
2703 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2704 //Add a new shape function with parameters
2705 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2706 if (aFunction.IsNull()) return NULL;
2708 //Check if the function is set correctly
2709 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2711 AdvancedEngine_IPipeTShape aData(aFunction);
2720 aData.SetHexMesh(theHexMesh);
2722 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2723 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2724 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2726 //Compute the resulting value
2729 if (!GetSolver()->ComputeFunction(aFunction)) {
2730 SetErrorCode("TShape driver failed");
2734 catch (Standard_Failure) {
2735 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2736 SetErrorCode(aFail->GetMessageString());
2741 TopoDS_Shape aShapeShape = aShape->GetValue();
2742 TopTools_IndexedMapOfShape anEdgesIndices;
2743 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2744 // Common edges on external cylinders
2745 Handle(GEOM_Object) box_e;
2747 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2750 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2752 box_e->GetLastFunction()->SetDescription("");
2753 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2754 box_e->GetLastFunction()->SetDescription("");
2756 Handle(TColStd_HSequenceOfInteger) edges_e =
2757 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2758 box_e->GetLastFunction()->SetDescription("");
2760 if (edges_e.IsNull() || edges_e->Length() == 0) {
2761 SetErrorCode("External edges not found");
2764 int nbEdgesInFillet = 0;
2765 std::list<int> theEdges;
2766 for (int i=1; i<=edges_e->Length();i++) {
2767 int edgeID = edges_e->Value(i);
2768 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2769 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2771 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2772 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2774 theEdges.push_back(edgeID);
2778 if (theHexMesh && nbEdgesInFillet == 1)
2782 Handle(GEOM_Object) aFillet;
2784 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2786 catch (Standard_Failure) {
2787 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2788 SetErrorCode(aFail->GetMessageString());
2791 if (aFillet.IsNull()) {
2792 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2793 SetErrorCode(myLocalOperations->GetErrorCode());
2796 aFillet->GetLastFunction()->SetDescription("");
2798 TopoDS_Shape aFilletShape = aFillet->GetValue();
2800 #ifdef FILLET_FIX_TOLERANCE
2801 // VSR: 30/12/2014: temporary workaround about Fillet problem
2803 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2806 GEOMUtils::FixShapeCurves(aFilletShape);
2810 aFunction->SetValue(aFilletShape);
2813 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2814 // the following block, when enabled, leads to partitioning problems
2816 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2817 // BEGIN: Limit tolerances (debug)
2818 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2819 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2820 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2821 aCorr1->GetLastFunction()->SetDescription("");
2822 // END: Limit tolerances (debug)
2823 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2825 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2828 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2830 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2834 // Add thickness reduction elements
2835 // at the three extremities: Left, Right and Incident
2838 if (isTRL || isTRR || isTRI) {
2839 TopoDS_Shape aResShape =
2840 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2841 theRL, theWL, theLtransL, theLthinL,
2842 theRR, theWR, theLtransR, theLthinR,
2843 theRI, theWI, theLtransI, theLthinI,
2845 aFunction->SetValue(aResShape);
2848 catch (Standard_Failure) {
2849 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2850 SetErrorCode(aFail->GetMessageString());
2854 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2855 aSeq->Append(aShape);
2860 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2861 0., 0., theRF, aSeq, gp_Trsf()))
2865 // Get internal group.
2866 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2867 theRR, theLtransR, theRI, theLtransI,
2872 catch (Standard_Failure) {
2873 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2874 SetErrorCode(aFail->GetMessageString());
2878 //Make a Python command
2879 TCollection_AsciiString anEntry, aListRes("[");
2880 // Iterate over the sequence aSeq
2881 Standard_Integer aNbGroups = aSeq->Length();
2882 Standard_Integer i = 1;
2883 for (; i <= aNbGroups; i++) {
2884 Handle(Standard_Transient) anItem = aSeq->Value(i);
2885 if (anItem.IsNull()) continue;
2886 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2887 if (aGroup.IsNull()) continue;
2888 //Make a Python command
2889 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2890 aListRes += anEntry + ", ";
2892 aListRes.Trunc(aListRes.Length() - 2);
2894 GEOM::TPythonDump pd (aFunction);
2896 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2897 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2898 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2899 << theRF << ", " << theHexMesh;
2901 // thickness reduction
2903 pd << ", theRL=" << theRL << ", theWL=" << theWL
2904 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2906 pd << ", theRR=" << theRR << ", theWR=" << theWR
2907 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2909 pd << ", theRI=" << theRI << ", theWI=" << theWI
2910 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2919 //=============================================================================
2921 * MakePipeTShapeFilletWithPosition
2922 * \brief Create a T-shape object with specified caracteristics for the main and
2923 * the incident pipes (radius, width, half-length). A fillet is created
2924 * on the junction of the pipes.
2925 * The extremities of the main pipe are located on junctions points P1 and P2.
2926 * The extremity of the incident pipe is located on junction point P3.
2927 * \param theR1 Internal radius of main pipe
2928 * \param theW1 Width of main pipe
2929 * \param theL1 Half-length of main pipe
2930 * \param theR2 Internal radius of incident pipe (R2 < R1)
2931 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2932 * \param theL2 Half-length of incident pipe
2933 * \param theRF Radius of curvature of fillet
2934 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2935 * \param theP1 1st junction point of main pipe
2936 * \param theP2 2nd junction point of main pipe
2937 * \param theP3 Junction point of incident pipe
2938 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2940 //=============================================================================
2941 Handle(TColStd_HSequenceOfTransient)
2942 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2943 (double theR1, double theW1, double theL1,
2944 double theR2, double theW2, double theL2,
2945 double theRL, double theWL, double theLtransL, double theLthinL,
2946 double theRR, double theWR, double theLtransR, double theLthinR,
2947 double theRI, double theWI, double theLtransI, double theLthinI,
2948 double theRF, bool theHexMesh,
2949 Handle(GEOM_Object) theP1,
2950 Handle(GEOM_Object) theP2,
2951 Handle(GEOM_Object) theP3)
2955 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2956 //Add a new shape function with parameters
2957 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2958 if (aFunction.IsNull()) return NULL;
2960 //Check if the function is set correctly
2961 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2963 // Check new position
2964 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2968 AdvancedEngine_IPipeTShape aData(aFunction);
2977 aData.SetHexMesh(theHexMesh);
2979 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2980 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2981 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2983 //Compute the resulting value
2986 if (!GetSolver()->ComputeFunction(aFunction)) {
2987 SetErrorCode("TShape driver failed");
2991 catch (Standard_Failure) {
2992 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2993 SetErrorCode(aFail->GetMessageString());
2998 TopoDS_Shape aShapeShape = aShape->GetValue();
2999 TopTools_IndexedMapOfShape anEdgesIndices;
3000 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3001 // Common edges on external cylinders
3002 Handle(GEOM_Object) box_e;
3004 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3007 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3009 box_e->GetLastFunction()->SetDescription("");
3010 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3011 box_e->GetLastFunction()->SetDescription("");
3013 Handle(TColStd_HSequenceOfInteger) edges_e =
3014 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3015 box_e->GetLastFunction()->SetDescription("");
3017 if (edges_e.IsNull() || edges_e->Length() == 0) {
3018 SetErrorCode("External edges not found");
3021 int nbEdgesInFillet = 0;
3022 std::list<int> theEdges;
3023 for (int i=1; i<=edges_e->Length();i++) {
3024 int edgeID = edges_e->Value(i);
3025 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3026 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3028 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3029 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3031 theEdges.push_back(edgeID);
3035 if (theHexMesh && nbEdgesInFillet == 1)
3039 Handle(GEOM_Object) aFillet;
3041 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3043 catch (Standard_Failure) {
3044 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3045 SetErrorCode(aFail->GetMessageString());
3048 if (aFillet.IsNull()) {
3049 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3052 aFillet->GetLastFunction()->SetDescription("");
3054 TopoDS_Shape aFilletShape = aFillet->GetValue();
3056 #ifdef FILLET_FIX_TOLERANCE
3057 // VSR: 30/12/2014: temporary workaround about Fillet problem
3059 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3062 GEOMUtils::FixShapeCurves(aFilletShape);
3066 aFunction->SetValue(aFilletShape);
3069 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3070 // the following block, when enabled, leads to partitioning problems
3072 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3073 // BEGIN: Limit tolerances (debug)
3074 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3075 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3076 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3077 aCorr1->GetLastFunction()->SetDescription("");
3078 // END: Limit tolerances (debug)
3079 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3081 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3084 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3086 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3090 // Add thickness reduction elements
3091 // at the three extremities: Left, Right and Incident
3094 if (isTRL || isTRR || isTRI) {
3095 TopoDS_Shape aResShape =
3096 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3097 theRL, theWL, theLtransL, theLthinL,
3098 theRR, theWR, theLtransR, theLthinR,
3099 theRI, theWI, theLtransI, theLthinI,
3101 aFunction->SetValue(aResShape);
3104 catch (Standard_Failure) {
3105 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3106 SetErrorCode(aFail->GetMessageString());
3111 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3112 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3113 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3114 aFunction->SetValue(aTrsf_Shape);
3116 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3117 aSeq->Append(aShape);
3122 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3123 0., 0., theRF, aSeq, aTrsf))
3127 // Get internal group.
3128 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3129 theRR, theLtransR, theRI, theLtransI,
3134 catch (Standard_Failure) {
3135 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3136 SetErrorCode(aFail->GetMessageString());
3140 //Make a Python command
3141 TCollection_AsciiString anEntry, aListRes("[");
3142 // Iterate over the sequence aSeq
3143 Standard_Integer aNbGroups = aSeq->Length();
3144 Standard_Integer i = 1;
3145 for (; i <= aNbGroups; i++) {
3146 Handle(Standard_Transient) anItem = aSeq->Value(i);
3147 if (anItem.IsNull()) continue;
3148 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3149 if (aGroup.IsNull()) continue;
3150 //Make a Python command
3151 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3152 aListRes += anEntry + ", ";
3154 aListRes.Trunc(aListRes.Length() - 2);
3156 GEOM::TPythonDump pd (aFunction);
3158 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3159 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3160 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3161 << theRF << ", " << theHexMesh << ", "
3162 << theP1 << ", " << theP2 << ", " << theP3;
3164 // thickness reduction
3166 pd << ", theRL=" << theRL << ", theWL=" << theWL
3167 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3169 pd << ", theRR=" << theRR << ", theWR=" << theWR
3170 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3172 pd << ", theRI=" << theRI << ", theWI=" << theWI
3173 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3182 //=============================================================================
3184 * This function allows to create a disk already divided into blocks. It can be
3185 * used to create divided pipes for later meshing in hexaedra.
3186 * \param theR Radius of the disk
3187 * \param theRatio Relative size of the central square diagonal against the disk diameter
3188 * \param theOrientation Plane on which the disk will be built
3189 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3190 * \return New GEOM_Object, containing the created shape.
3192 //=============================================================================
3193 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3194 int theOrientation, int thePattern)
3198 if (theOrientation != 1 &&
3199 theOrientation != 2 &&
3200 theOrientation != 3)
3202 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3206 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3208 //Add a new shape function with parameters
3209 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3210 if (aFunction.IsNull()) return NULL;
3212 //Check if the function is set correctly
3213 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3215 AdvancedEngine_IDividedDisk aData (aFunction);
3218 aData.SetRatio(theRatio);
3219 aData.SetOrientation(theOrientation);
3220 aData.SetType(thePattern);
3222 //Compute the resulting value
3225 if (!GetSolver()->ComputeFunction(aFunction)) {
3226 SetErrorCode("DividedDisk driver failed");
3230 catch (Standard_Failure) {
3231 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3232 SetErrorCode(aFail->GetMessageString());
3236 std::string aPatternStr;
3241 aPatternStr = "GEOM.SQUARE";
3244 aPatternStr = "GEOM.HEXAGON";
3248 //Make a Python command
3249 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3256 //=============================================================================
3258 * This function allows to create a disk already divided into blocks. It can be
3259 * used to create divided pipes for later meshing in hexaedra.
3260 * \param theR Radius of the disk
3261 * \param theRatio Relative size of the central square diagonal against the disk diameter
3262 * \return New GEOM_Object, containing the created shape.
3264 //=============================================================================
3265 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3266 Handle(GEOM_Object) theVec,
3274 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3276 //Add a new shape function with parameters
3277 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3278 if (aFunction.IsNull()) return NULL;
3280 //Check if the function is set correctly
3281 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3283 AdvancedEngine_IDividedDisk aData (aFunction);
3285 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3286 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3288 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3290 aData.SetCenter(aRefPnt);
3291 aData.SetVector(aRefVec);
3294 aData.SetRatio(theRatio);
3295 aData.SetType(thePattern);
3297 //Compute the resulting value
3300 if (!GetSolver()->ComputeFunction(aFunction)) {
3301 SetErrorCode("DividedDisk driver failed");
3305 catch (Standard_Failure) {
3306 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3307 SetErrorCode(aFail->GetMessageString());
3311 std::string aPatternStr;
3316 aPatternStr = "GEOM.SQUARE";
3319 aPatternStr = "GEOM.HEXAGON";
3324 //Make a Python command
3325 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3332 //=============================================================================
3334 * Builds a cylinder prepared for hexa meshes
3335 * \param theR Radius of the cylinder
3336 * \param theH Height of the cylinder
3337 * \return New GEOM_Object, containing the created shape.
3339 //=============================================================================
3340 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3347 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3349 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3350 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3352 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3354 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3355 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3356 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3358 std::string aPatternStr;
3363 aPatternStr = "GEOM.SQUARE";
3366 aPatternStr = "GEOM.HEXAGON";
3370 //Make a Python command
3371 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3377 //=============================================================================
3379 * Create a smoothing surface from a set of points
3380 * \param thelPoints list of points or compounds of points
3381 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3382 * \param theDegMax maximum degree of the resulting BSpline surface
3383 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3384 * \return New GEOM_Object, containing the created shape.
3386 //=============================================================================
3387 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3395 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3397 //Add a new shape function with parameters
3398 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3399 if (aFunction.IsNull()) return NULL;
3401 //Check if the function is set correctly
3402 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3404 AdvancedEngine_ISmoothingSurface aData (aFunction);
3406 int aLen = thelPoints.size();
3407 aData.SetLength(aLen);
3409 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3410 for (; it != thelPoints.end(); it++, ind++) {
3411 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3412 if (aRefObj.IsNull()) {
3413 SetErrorCode("NULL point or compound for bSplineFaceShape");
3416 aData.SetPntOrComp(ind, aRefObj);
3419 aData.SetNbMax(theNbMax);
3420 aData.SetDegMax(theDegMax);
3421 aData.SetDMax(theDMax);
3423 //Compute the resulting value
3426 if (!GetSolver()->ComputeFunction(aFunction)) {
3427 SetErrorCode("SmoothingSurface driver failed");
3431 catch (Standard_Failure) {
3432 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3433 SetErrorCode(aFail->GetMessageString());
3437 //Make a Python command
3438 GEOM::TPythonDump pd (aFunction);
3439 pd << aShape << " = geompy.MakeSmoothingSurface([";
3440 it = thelPoints.begin();
3442 while (it != thelPoints.end()) {
3443 pd << ", " << (*it++);
3447 << theDegMax << ", "