Back to index

salome-geom  6.5.0
GEOMImpl_BlockDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include <Standard_Stream.hxx>
00024 
00025 #include <BRepOffsetAPI_MakeFilling.hxx>
00026 
00027 #include <GEOMImpl_BlockDriver.hxx>
00028 #include <GEOMImpl_IBlocks.hxx>
00029 #include <GEOMImpl_IBlockTrsf.hxx>
00030 #include <GEOMImpl_GlueDriver.hxx>
00031 #include <GEOMImpl_Types.hxx>
00032 #include <GEOMImpl_ILocalOperations.hxx>
00033 #include <GEOMImpl_Block6Explorer.hxx>
00034 #include <GEOMImpl_IBlocksOperations.hxx>
00035 
00036 #include <GEOM_Function.hxx>
00037 
00038 #include <ShHealOper_Sewing.hxx>
00039 #include <ShHealOper_ShapeProcess.hxx>
00040 //#include <GEOMAlgo_Gluer.hxx>
00041 #include <BlockFix_BlockFixAPI.hxx>
00042 
00043 #include "utilities.h"
00044 
00045 #include <TNaming_CopyShape.hxx>
00046 
00047 #include <BRepAdaptor_Curve.hxx>
00048 #include <BRepLib.hxx>
00049 #include <BRep_Tool.hxx>
00050 #include <BRepTools.hxx>
00051 #include <BRepGProp.hxx>
00052 #include <BRep_Builder.hxx>
00053 #include <BRepTools_Quilt.hxx>
00054 #include <BRepTools_WireExplorer.hxx>
00055 #include <BRepBuilderAPI_MakeEdge.hxx>
00056 #include <BRepBuilderAPI_MakeWire.hxx>
00057 #include <BRepBuilderAPI_MakePolygon.hxx>
00058 #include <BRepBuilderAPI_Transform.hxx>
00059 #include <BRepCheck_Analyzer.hxx>
00060 #include <BRepClass_FaceClassifier.hxx>
00061 #include <BRepClass3d_SolidClassifier.hxx>
00062 #include <BRepExtrema_ExtPF.hxx>
00063 #include <BRepExtrema_DistShapeShape.hxx>
00064 
00065 #include <TopAbs.hxx>
00066 #include <TopoDS.hxx>
00067 #include <TopoDS_Shape.hxx>
00068 #include <TopoDS_Edge.hxx>
00069 #include <TopoDS_Wire.hxx>
00070 #include <TopoDS_Shell.hxx>
00071 #include <TopoDS_Solid.hxx>
00072 #include <TopoDS_Compound.hxx>
00073 #include <TopoDS_Iterator.hxx>
00074 #include <TopExp.hxx>
00075 #include <TopExp_Explorer.hxx>
00076 #include <TopTools_MapOfShape.hxx>
00077 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00078 #include <TopTools_Array1OfShape.hxx>
00079 #include <TopTools_SequenceOfShape.hxx>
00080 #include <TopTools_ListOfShape.hxx>
00081 #include <TopTools_ListIteratorOfListOfShape.hxx>
00082 #include <TopTools_IndexedMapOfShape.hxx>
00083 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00084 
00085 #include <GProp_GProps.hxx>
00086 
00087 #include <Geom_Line.hxx>
00088 #include <GC_MakeLine.hxx>
00089 
00090 #include <gp.hxx>
00091 #include <gp_Pnt.hxx>
00092 #include <gp_Ax3.hxx>
00093 #include <Precision.hxx>
00094 #include <TColgp_Array1OfPnt.hxx>
00095 #include <TColStd_Array1OfInteger.hxx>
00096 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
00097 #include <StdFail_NotDone.hxx>
00098 #include <Standard_NullObject.hxx>
00099 #include <Standard_TypeMismatch.hxx>
00100 #include <Standard_ConstructionError.hxx>
00101 
00102 //=======================================================================
00103 //function : GetID
00104 //purpose  :
00105 //=======================================================================
00106 const Standard_GUID& GEOMImpl_BlockDriver::GetID()
00107 {
00108   static Standard_GUID aBlockDriver("FF1BBB67-5D14-4df2-980B-3A668264EA16");
00109   return aBlockDriver;
00110 }
00111 
00112 
00113 //=======================================================================
00114 //function : GEOMImpl_BlockDriver
00115 //purpose  :
00116 //=======================================================================
00117 GEOMImpl_BlockDriver::GEOMImpl_BlockDriver()
00118 {
00119 }
00120 
00121 //=======================================================================
00122 //function : Execute
00123 //purpose  :
00124 //=======================================================================
00125 Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const
00126 {
00127   if (Label().IsNull()) return 0;
00128   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00129 
00130   Standard_Integer aType = aFunction->GetType();
00131 
00132   TopoDS_Shape aShape;
00133   BRep_Builder B;
00134 
00135   Standard_Real prec = Precision::Confusion();
00136 
00137   Standard_Integer aNbSub = 0;
00138   if (aType == BLOCK_COMPOUND_GLUE) {
00139 
00140     aNbSub = 1;
00141 
00142   } else if (aType == BLOCK_FACE_TWO_EDGES ||
00143              aType == BLOCK_TWO_FACES) {
00144 
00145     aNbSub = 2;
00146 
00147   } else if (aType == BLOCK_FACE_FOUR_PNT ||
00148              aType == BLOCK_FACE_FOUR_EDGES) {
00149 
00150     aNbSub = 4;
00151 
00152   } else if (aType == BLOCK_SIX_FACES) {
00153 
00154     aNbSub = 6;
00155 
00156   } else {
00157   }
00158 
00159   if (aNbSub > 0) {
00160     GEOMImpl_IBlocks aCI (aFunction);
00161     Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
00162     Standard_Integer nbshapes = aShapes->Length();
00163 
00164     if (nbshapes != aNbSub) {
00165       Standard_TypeMismatch::Raise
00166         ("Number of elements for object construction does not correspond to the used constructor");
00167     }
00168 
00169     TopTools_Array1OfShape anArgs (1, aNbSub);
00170     Standard_Integer argi;
00171     for (argi = 1; argi <= aNbSub; argi++) {
00172       Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(aShapes->Value(argi));
00173       TopoDS_Shape anArg = aRef->GetValue();
00174       if (anArg.IsNull()) {
00175         Standard_NullObject::Raise("Null shape is given as argument");
00176       }
00177       anArgs(argi) = anArg;
00178     }
00179 
00180     if (aType == BLOCK_FACE_FOUR_EDGES) {
00181 
00182       // Make face from four edges
00183       if (anArgs(1).ShapeType() != TopAbs_EDGE || anArgs(2).ShapeType() != TopAbs_EDGE ||
00184           anArgs(3).ShapeType() != TopAbs_EDGE || anArgs(4).ShapeType() != TopAbs_EDGE) {
00185         Standard_TypeMismatch::Raise("Shape for face construction is not an edge");
00186       }
00187 
00188       // count corner vertices
00189       TopTools_MapOfShape aVertMap;
00190       for (Standard_Integer ii = 1; ii <= 4; ii++) {
00191         TopoDS_Edge anEdge = TopoDS::Edge(anArgs(ii));
00192         TopoDS_Vertex V1, V2;
00193         TopExp::Vertices(anEdge, V1, V2, Standard_True);
00194         if (V1.IsNull() || V2.IsNull()) {
00195           Standard_NullObject::Raise("Bad edge for face construction: vertex is not defined");
00196         }
00197         if (BRepTools::Compare(V1,V2)) {
00198           Standard_ConstructionError::Raise("Edge ends are too close");
00199         }
00200         Standard_Boolean isCoin1 = Standard_False, isCoin2 = Standard_False;
00201         TopTools_MapIteratorOfMapOfShape anIter (aVertMap);
00202         for (; anIter.More(); anIter.Next()) {
00203           TopoDS_Vertex V = TopoDS::Vertex(anIter.Key());
00204           if (BRepTools::Compare(V,V1)) isCoin1 = Standard_True;
00205           if (BRepTools::Compare(V,V2)) isCoin2 = Standard_True;
00206         }
00207         if (!isCoin1) aVertMap.Add(V1);
00208         if (!isCoin2) aVertMap.Add(V2);
00209       }
00210       if (aVertMap.Extent() != 4) {
00211         Standard_ConstructionError::Raise("The edges must form a closed wire");
00212       }
00213 
00214       TopoDS_Edge anEdge1 = TopoDS::Edge(anArgs(1));
00215       TopoDS_Edge anEdge2 = TopoDS::Edge(anArgs(2));
00216       TopoDS_Edge anEdge3 = TopoDS::Edge(anArgs(3));
00217       TopoDS_Edge anEdge4 = TopoDS::Edge(anArgs(4));
00218 
00219       // check, if anEdge1 has common/coincident vertex with anEdge2,
00220       Standard_Boolean isConnected12 = Standard_False;
00221       TopoDS_Vertex V11, V12, V21, V22;
00222       TopExp::Vertices(anEdge1, V11, V12, Standard_True);
00223       TopExp::Vertices(anEdge2, V21, V22, Standard_True);
00224       if (BRepTools::Compare(V11,V21) || BRepTools::Compare(V11,V22) ||
00225           BRepTools::Compare(V12,V21) || BRepTools::Compare(V12,V22)) {
00226         // the edges have common vertex
00227         isConnected12 = Standard_True;
00228       }
00229 
00230       // build wire in right order, corresponding to edges connexity
00231       BRepBuilderAPI_MakeWire* MW;
00232       if (isConnected12)
00233         MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3, anEdge4);
00234       else
00235         MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge3, anEdge2, anEdge4);
00236 
00237       if (!MW->IsDone()) {
00238         Standard_ConstructionError::Raise
00239           ("Impossible to build a connected wire from the given edges");
00240       }
00241       TopoDS_Wire aWire = *MW;
00242       delete MW;
00243 
00244       // check the wire closure
00245       TopoDS_Vertex aV1, aV2;
00246       TopExp::Vertices(aWire, aV1, aV2);
00247       if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
00248         aWire.Closed( true );
00249 
00250       if (!aWire.Closed()) {
00251         Standard_ConstructionError::Raise
00252           ("Impossible to build a closed wire from the given edges");
00253       }
00254 
00255       // try to build face on the wire
00256       GEOMImpl_Block6Explorer::MakeFace(aWire, Standard_False, aShape);
00257       if (aShape.IsNull()) {
00258         Standard_ConstructionError::Raise("Face construction failed");
00259       }
00260 
00261     } else if (aType == BLOCK_FACE_TWO_EDGES) {
00262 
00263       // Make face from two opposite edges
00264       if (anArgs(1).ShapeType() != TopAbs_EDGE ||
00265           anArgs(2).ShapeType() != TopAbs_EDGE) {
00266         Standard_TypeMismatch::Raise("Shape for face construction is not an edge");
00267       }
00268 
00269       TopoDS_Edge anEdge1 = TopoDS::Edge(anArgs(1));
00270       TopoDS_Edge anEdge2 = TopoDS::Edge(anArgs(2));
00271 
00272       if (anEdge1.IsSame(anEdge2)) {
00273         Standard_ConstructionError::Raise("The edges must be different");
00274       }
00275 
00276       // create two edges, linking ends of the given edges
00277       TopoDS_Vertex V11, V12, V21, V22;
00278       TopExp::Vertices(anEdge1, V11, V12, Standard_False);
00279       TopExp::Vertices(anEdge2, V21, V22, Standard_False);
00280       if (V11.IsNull() || V12.IsNull() ||
00281           V21.IsNull() || V22.IsNull()) {
00282         Standard_NullObject::Raise("Bad edge for face construction: vertex is not defined");
00283       }
00284 
00285       BRepAdaptor_Curve C1 (anEdge1);
00286       BRepAdaptor_Curve C2 (anEdge2);
00287       gp_Pnt P11, P12, P21, P22;
00288 
00289       // Mantis issue 0020599: Creation of a quadrangle face from 2 edges: SIGSEGV
00290       P11 = C1.Value(C1.FirstParameter());
00291       P12 = C1.Value(C1.LastParameter());
00292       P21 = C2.Value(C2.FirstParameter());
00293       P22 = C2.Value(C2.LastParameter());
00294       //gp_Pnt P11 = BRep_Tool::Pnt(V11);
00295       //gp_Pnt P12 = BRep_Tool::Pnt(V12);
00296       //gp_Pnt P21 = BRep_Tool::Pnt(V21);
00297       //gp_Pnt P22 = BRep_Tool::Pnt(V22);
00298 
00299       if (P11.Distance(P21) < prec || P12.Distance(P22) < prec ||
00300           P11.Distance(P22) < prec || P12.Distance(P21) < prec) {
00301         Standard_ConstructionError::Raise("Given edges have too close ends");
00302       }
00303 
00304       Standard_Real per11 = P11.Distance(P21) + P12.Distance(P22);
00305       Standard_Real per12 = P11.Distance(P22) + P12.Distance(P21);
00306 
00307       BRep_Builder BB;
00308 
00309       TopoDS_Edge anEdge3;
00310       TopoDS_Edge anEdge4;
00311 
00312       // Mantis issue 0020599: Creation of a quadrangle face from 2 edges: SIGSEGV
00313       if (per11 < per12) {
00314         Handle(Geom_Line) Line1 = GC_MakeLine(P11, P21).Value();
00315         Handle(Geom_Line) Line2 = GC_MakeLine(P12, P22).Value();
00316 
00317         BB.MakeEdge(anEdge3, Line1, Precision::Confusion());
00318         BB.Range(anEdge3, 0., P11.Distance(P21));
00319         BB.Add(anEdge3, V11.Oriented(TopAbs_FORWARD));
00320         BB.Add(anEdge3, V21.Oriented(TopAbs_REVERSED));
00321 
00322         BB.MakeEdge(anEdge4, Line2, Precision::Confusion());
00323         BB.Range(anEdge4, 0., P12.Distance(P22));
00324         BB.Add(anEdge4, V12.Oriented(TopAbs_FORWARD));
00325         BB.Add(anEdge4, V22.Oriented(TopAbs_REVERSED));
00326       }
00327       else {
00328         Handle(Geom_Line) Line1 = GC_MakeLine(P11, P22).Value();
00329         Handle(Geom_Line) Line2 = GC_MakeLine(P12, P21).Value();
00330 
00331         BB.MakeEdge(anEdge3, Line1, Precision::Confusion());
00332         BB.Range(anEdge3, 0., P11.Distance(P22));
00333         BB.Add(anEdge3, V11.Oriented(TopAbs_FORWARD));
00334         BB.Add(anEdge3, V22.Oriented(TopAbs_REVERSED));
00335 
00336         BB.MakeEdge(anEdge4, Line2, Precision::Confusion());
00337         BB.Range(anEdge4, 0., P12.Distance(P21));
00338         BB.Add(anEdge4, V12.Oriented(TopAbs_FORWARD));
00339         BB.Add(anEdge4, V21.Oriented(TopAbs_REVERSED));
00340       }
00341       //if (per11 < per12) {
00342       //  anEdge3 = BRepBuilderAPI_MakeEdge(V11, V21);
00343       //  anEdge4 = BRepBuilderAPI_MakeEdge(V12, V22);
00344       //} else {
00345       //  anEdge3 = BRepBuilderAPI_MakeEdge(V11, V22);
00346       //  anEdge4 = BRepBuilderAPI_MakeEdge(V12, V21);
00347       //}
00348 
00349       // build a wire
00350       BRepBuilderAPI_MakeWire* MW;
00351       MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge3, anEdge2, anEdge4);
00352       if (!MW->IsDone()) {
00353         Standard_ConstructionError::Raise("Wire construction failed");
00354       }
00355 
00356       TopoDS_Wire aWire = *MW;
00357       delete MW;
00358 
00359       TopoDS_Vertex aV1, aV2;
00360       TopExp::Vertices(aWire, aV1, aV2);
00361       if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) )
00362         aWire.Closed( true );
00363 
00364       if (!aWire.Closed()) {
00365         Standard_ConstructionError::Raise
00366           ("Impossible to build a closed wire from the given edges");
00367       }
00368 
00369       // try to build face on the wire
00370       GEOMImpl_Block6Explorer::MakeFace(aWire, Standard_False, aShape);
00371       if (aShape.IsNull()) {
00372         Standard_ConstructionError::Raise("Face construction failed");
00373       }
00374 
00375     } else if (aType == BLOCK_FACE_FOUR_PNT) {
00376 
00377       // Make face from four corner vertices
00378       if (anArgs(1).ShapeType() != TopAbs_VERTEX ||
00379           anArgs(2).ShapeType() != TopAbs_VERTEX ||
00380           anArgs(3).ShapeType() != TopAbs_VERTEX ||
00381           anArgs(4).ShapeType() != TopAbs_VERTEX) {
00382         Standard_TypeMismatch::Raise("Shape for face construction is not a vertex");
00383       }
00384 
00385       TopoDS_Vertex V1 = TopoDS::Vertex(anArgs(1));
00386       TopoDS_Vertex V2 = TopoDS::Vertex(anArgs(2));
00387       TopoDS_Vertex V3 = TopoDS::Vertex(anArgs(3));
00388       TopoDS_Vertex V4 = TopoDS::Vertex(anArgs(4));
00389 
00390       gp_Pnt P1 = BRep_Tool::Pnt(V1);
00391       gp_Pnt P2 = BRep_Tool::Pnt(V2);
00392       gp_Pnt P3 = BRep_Tool::Pnt(V3);
00393       gp_Pnt P4 = BRep_Tool::Pnt(V4);
00394 
00395       if (P1.Distance(P2) < prec || P1.Distance(P3) < prec ||
00396           P1.Distance(P4) < prec || P2.Distance(P3) < prec ||
00397           P2.Distance(P4) < prec || P3.Distance(P4) < prec) {
00398         Standard_ConstructionError::Raise("Four not coincident points must be given");
00399       }
00400 
00401       // calculate perimeters
00402       Standard_Real per1234 = P1.Distance(P2) + P2.Distance(P3) +
00403                               P3.Distance(P4) + P4.Distance(P1);
00404       Standard_Real per1243 = P1.Distance(P2) + P2.Distance(P4) +
00405                               P4.Distance(P3) + P3.Distance(P1);
00406       Standard_Real per1324 = P1.Distance(P3) + P3.Distance(P2) +
00407                               P2.Distance(P4) + P4.Distance(P1);
00408 
00409       // order vertices
00410       if (per1243 < per1234 && per1243 < per1324) {
00411         TopoDS_Vertex Vtmp = V3;
00412         V3 = V4;
00413         V4 = Vtmp;
00414       } else if (per1324 < per1234 && per1324 < per1243) {
00415         TopoDS_Vertex Vtmp = V3;
00416         V3 = V2;
00417         V2 = Vtmp;
00418       } else {
00419       }
00420 
00421       // build wire
00422       BRepBuilderAPI_MakePolygon aMkPoly (V1, V2, V3, V4, Standard_True);
00423       if (!aMkPoly.IsDone()) {
00424         Standard_ConstructionError::Raise("Polygon construction failed");
00425       }
00426 
00427       // try to build face on the wire
00428       aMkPoly.Close();
00429       GEOMImpl_Block6Explorer::MakeFace(aMkPoly, Standard_False, aShape);
00430       if (aShape.IsNull()) {
00431         Standard_ConstructionError::Raise("Face construction failed");
00432       }
00433 
00434     } else if (aType == BLOCK_SIX_FACES || aType == BLOCK_TWO_FACES) {
00435 
00436       BRepTools_Quilt Glue;
00437 
00438       if (aType == BLOCK_SIX_FACES) {
00439         // Make block (hexahedral solid) from six faces
00440         for (Standard_Integer ind = 1; ind <= nbshapes; ind++) {
00441           if (anArgs(ind).ShapeType() != TopAbs_FACE) {
00442             Standard_TypeMismatch::Raise("Shape for block construction is not a face");
00443           }
00444           Glue.Add(anArgs(ind));
00445         }
00446 
00447       }
00448       else {
00449         // Make block (hexahedral solid) from two opposite faces
00450         if (anArgs(1).ShapeType() != TopAbs_FACE ||
00451             anArgs(2).ShapeType() != TopAbs_FACE) {
00452           Standard_TypeMismatch::Raise("Shape for block construction is not a face");
00453         }
00454 
00455         // Get wires of the given faces
00456         TopExp_Explorer wires1 (anArgs(1), TopAbs_WIRE);
00457         TopExp_Explorer wires2 (anArgs(2), TopAbs_WIRE);
00458         if (!wires1.More() || !wires2.More()) {
00459           Standard_ConstructionError::Raise("A face for the block has no wires");
00460         }
00461         TopoDS_Shape aWire1 = wires1.Current();
00462         TopoDS_Shape aWire2 = wires2.Current();
00463         wires1.Next();
00464         wires2.Next();
00465         if (wires1.More() || wires2.More()) {
00466           Standard_ConstructionError::Raise("A face for the block has more than one wire");
00467         }
00468 
00469         GEOMImpl_Block6Explorer aBlockTool;
00470         aBlockTool.InitByTwoFaces(anArgs(1), anArgs(2));
00471 
00472         // Construct the linking faces and add them in the gluing tool
00473         Glue.Add(anArgs(1));
00474         Glue.Add(aBlockTool.GetFace(3, Standard_True));
00475         Glue.Add(aBlockTool.GetFace(4, Standard_True));
00476         Glue.Add(aBlockTool.GetFace(5, Standard_True));
00477         Glue.Add(aBlockTool.GetFace(6, Standard_True));
00478         Glue.Add(anArgs(2));
00479       }
00480 
00481       TopExp_Explorer exp (Glue.Shells(), TopAbs_SHELL);
00482       Standard_Integer ish = 0;
00483       TopTools_MapOfShape mapShape;
00484       for (; exp.More(); exp.Next()) {
00485         if (mapShape.Add(exp.Current())) {
00486           aShape = exp.Current();
00487           ish++;
00488         }
00489       }
00490 
00491       if (ish > 1) {
00492         aShape = Glue.Shells();
00493         Standard_Real aTol = prec; // Precision::Confusion()
00494         TopExp_Explorer expF (aShape, TopAbs_FACE);
00495         TopTools_MapOfShape mapF;
00496         TopoDS_Shell Shell;
00497         B.MakeShell(Shell);
00498         for (; expF.More(); expF.Next()) {
00499           if (mapF.Add(expF.Current())) {
00500             B.Add(Shell, expF.Current());
00501             Standard_Real aToler = BRep_Tool::Tolerance(TopoDS::Face(expF.Current()));
00502             if (aToler > aTol)
00503               aTol = aToler;
00504           }
00505         }
00506         ShHealOper_Sewing aHealer (Shell, aTol);
00507         if (aHealer.Perform())
00508           aShape = aHealer.GetResultShape();
00509         else
00510           Standard_ConstructionError::Raise
00511             ("Impossible to build a connected shell on the given faces");
00512       }
00513 
00514       if (aType == BLOCK_SIX_FACES) {
00515         if (!aShape.Closed()) {
00516           Standard_ConstructionError::Raise
00517             ("Impossible to build a closed shell on the given faces");
00518         }
00519       }
00520 
00521       TopoDS_Solid Sol;
00522       B.MakeSolid(Sol);
00523       B.Add(Sol, aShape);
00524       BRepClass3d_SolidClassifier SC (Sol);
00525       SC.PerformInfinitePoint(prec);
00526       if (SC.State() == TopAbs_IN) {
00527         B.MakeSolid(Sol);
00528         B.Add(Sol, aShape.Reversed());
00529       }
00530       aShape = Sol;
00531       BRepLib::SameParameter(aShape, 1.E-5, Standard_True);
00532     }
00533     else if (aType == BLOCK_COMPOUND_GLUE) {
00534       // Make blocks compound from a compound
00535       if (anArgs(1).ShapeType() != TopAbs_COMPOUND &&
00536           anArgs(2).ShapeType() != TopAbs_COMPSOLID) {
00537         Standard_TypeMismatch::Raise("Not a compound given");
00538       }
00539 
00540       TopoDS_Shape aCompound = anArgs(1);
00541 
00542       // Glue coincident faces and edges
00543       aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True);
00544       //GEOMAlgo_Gluer aGluer;
00545       //aGluer.SetShape(aCompound);
00546       //aGluer.SetCheckGeometry(Standard_True);
00547       //aGluer.Perform();
00548       //aShape = aGluer.Result();
00549     }
00550     else {
00551     }
00552 
00553   } else { // Multi-transformations and compound improving
00554 
00555     if (aType == BLOCK_REMOVE_EXTRA ||
00556         aType == BLOCK_COMPOUND_IMPROVE) {
00557 
00558       GEOMImpl_IBlockTrsf aCI (aFunction);
00559       Handle(GEOM_Function) aRefShape = aCI.GetOriginal();
00560       TopoDS_Shape aBlockOrComp = aRefShape->GetValue();
00561       if (aBlockOrComp.IsNull()) {
00562         Standard_NullObject::Raise("Null Shape given");
00563       }
00564 
00565       // 1. Improve solids with seam and/or degenerated edges
00566       BlockFix_BlockFixAPI aTool;
00567       //aTool.Tolerance() = toler;
00568       aTool.OptimumNbFaces() = aCI.GetOptimumNbFaces();
00569       aTool.SetShape(aBlockOrComp);
00570       aTool.Perform();
00571 
00572       TopoDS_Shape aFixedExtra = aTool.Shape();
00573 
00574       // Repair result
00575       BRepCheck_Analyzer ana (aFixedExtra, false);
00576       if (!ana.IsValid()) {
00577         TopoDS_Shape aFixed;
00578         ShHealOper_ShapeProcess aHealer;
00579         aHealer.Perform(aFixedExtra, aFixed);
00580         if (aHealer.isDone())
00581           aFixedExtra = aFixed;
00582       }
00583 
00584       if (aType == BLOCK_REMOVE_EXTRA)
00585       {
00586         aShape = aFixedExtra;
00587 
00588         if (aShape == aBlockOrComp) {
00589           MESSAGE("No modifications have been done");
00590         }
00591       }
00592       else // aType == BLOCK_COMPOUND_IMPROVE
00593       {
00594         // 2. Separate non-blocks
00595         TopTools_ListOfShape BLO; // All blocks from the given compound
00596         TopTools_ListOfShape NOT; // Not blocks
00597         TopTools_ListOfShape EXT; // Hexahedral solids, having degenerated and/or seam edges
00598         GEOMImpl_IBlocksOperations::AddBlocksFrom(aFixedExtra, BLO, NOT, EXT);
00599 
00600         if (NOT.Extent() > 0) {
00601           MESSAGE("Some non-blocks have been removed");
00602         }
00603 
00604         // 3. Warn about staying extra-edges
00605         if (EXT.Extent() > 0) {
00606           MESSAGE("Warning: Not all seam or degenerated edges was removed");
00607         }
00608 
00609         // ??? Throw away standalone blocks ???
00610 
00611         // 4. Create compound of all blocks
00612         TopoDS_Compound aComp;
00613         BRep_Builder BB;
00614         BB.MakeCompound(aComp);
00615         TopTools_ListIteratorOfListOfShape BLOit (BLO);
00616         for (; BLOit.More(); BLOit.Next()) {
00617           BB.Add(aComp, BLOit.Value());
00618         }
00619 
00620         // 5. Glue Faces
00621         aShape = GEOMImpl_GlueDriver::GlueFaces(aComp, Precision::Confusion(), Standard_False);
00622       }
00623 
00624     } else if (aType == BLOCK_MULTI_TRANSFORM_1D ||
00625                aType == BLOCK_MULTI_TRANSFORM_2D) {
00626 
00627       TopoDS_Shape aMulti;
00628       GEOMImpl_IBlockTrsf aCI (aFunction);
00629       Handle(GEOM_Function) aRefShape = aCI.GetOriginal();
00630       TopoDS_Shape aBlockIni = aRefShape->GetValue();
00631       if (aBlockIni.IsNull()) {
00632         Standard_NullObject::Raise("Null Block");
00633       }
00634 
00635       // Copy block to avoid problems (PAL6706)
00636       TColStd_IndexedDataMapOfTransientTransient aMap;
00637       TopoDS_Shape aBlock;
00638       TNaming_CopyShape::CopyTool(aBlockIni, aMap, aBlock);
00639 
00640       // Block tolerance in vertices
00641       Standard_Real aTol = prec;
00642       TopExp_Explorer expV (aBlock, TopAbs_VERTEX);
00643       TopTools_MapOfShape mapShape;
00644       for (; expV.More(); expV.Next()) {
00645         if (mapShape.Add(expV.Current())) {
00646           TopoDS_Vertex aV = TopoDS::Vertex(expV.Current());
00647           aTol = Max(BRep_Tool::Tolerance(aV), aTol);
00648         }
00649       }
00650 
00651       if (aType == BLOCK_MULTI_TRANSFORM_1D) {
00652         // Retrieve a faces by Ids
00653         Standard_Integer aFace1Id = aCI.GetFace1U();
00654         Standard_Integer aFace2Id = aCI.GetFace2U();
00655         TopoDS_Shape aFace1, aFace2;
00656         if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1Id, aFace1)) {
00657           Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id");
00658         }
00659         if (aFace1.ShapeType() != TopAbs_FACE) {
00660           Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face");
00661         }
00662 
00663         if (aFace2Id > 0) {
00664           if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2Id, aFace2)) {
00665             Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id");
00666           }
00667           if (aFace2.ShapeType() != TopAbs_FACE) {
00668             Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face");
00669           }
00670         }
00671 
00672         Standard_Integer aNbIter = aCI.GetNbIterU();
00673 
00674         MultiTransformate1D(aBlock, aFace1, aFace2, aNbIter, aMulti);
00675 
00676       } else { // aType == BLOCK_MULTI_TRANSFORM_2D
00677         // Retrieve a faces by Ids
00678         Standard_Integer aFace1UId = aCI.GetFace1U();
00679         Standard_Integer aFace2UId = aCI.GetFace2U();
00680         Standard_Integer aFace1VId = aCI.GetFace1V();
00681         Standard_Integer aFace2VId = aCI.GetFace2V();
00682 
00683         TopoDS_Shape aFace1U, aFace2U, aFace1V, aFace2V;
00684         if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1UId, aFace1U) ||
00685             !GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1VId, aFace1V)) {
00686           Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id");
00687         }
00688 
00689         if (aFace1U.ShapeType() != TopAbs_FACE ||
00690             aFace1V.ShapeType() != TopAbs_FACE) {
00691           Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face");
00692         }
00693 
00694         if (aFace2UId > 0) {
00695           if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2UId, aFace2U)) {
00696             Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id");
00697           }
00698 
00699           if (aFace2U.ShapeType() != TopAbs_FACE) {
00700             Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face");
00701           }
00702         }
00703 
00704         if (aFace2VId > 0) {
00705           if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2VId, aFace2V)) {
00706             Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id");
00707           }
00708 
00709           if (aFace2V.ShapeType() != TopAbs_FACE) {
00710             Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face");
00711           }
00712         }
00713 
00714         Standard_Integer aNbIterU = aCI.GetNbIterU();
00715         Standard_Integer aNbIterV = aCI.GetNbIterV();
00716 
00717         MultiTransformate2D(aBlock,
00718                             aFace1U, aFace2U, aNbIterU,
00719                             aFace1V, aFace2V, aNbIterV, aMulti);
00720       }
00721 
00722       if (aMulti.IsNull()) {
00723         StdFail_NotDone::Raise("Multi-transformation failed");
00724       }
00725 
00726       // Glue faces of the multi-block
00727       aShape = GEOMImpl_GlueDriver::GlueFaces(aMulti, aTol, Standard_False);
00728 
00729     } else { // unknown function type
00730       return 0;
00731     }
00732   }
00733 
00734   if (aShape.IsNull()) return 0;
00735 
00736   aFunction->SetValue(aShape);
00737 
00738   log.SetTouched(Label());
00739 
00740   return 1;
00741 }
00742 
00743 //=======================================================================
00744 //function :  MultiTransformate1D
00745 //purpose  :
00746 //=======================================================================
00747 void GEOMImpl_BlockDriver::MultiTransformate1D (const TopoDS_Shape&    theBlock,
00748                                                 const TopoDS_Shape&    theFace1,
00749                                                 const TopoDS_Shape&    theFace2,
00750                                                 const Standard_Integer theNbIter,
00751                                                 TopoDS_Shape&          theResult) const
00752 {
00753   // Construct Tool, where <theFace1> will be the first face,
00754   // and a face, opposite to <theFace1>, will be the second face
00755   GEOMImpl_Block6Explorer aBlockTool;
00756   aBlockTool.InitByBlockAndFace(theBlock, theFace1);
00757 
00758   // Find IDs of the faces
00759   Standard_Integer dir_face1 = 1, dir_face2 = 2;
00760   if (!theFace2.IsNull()) {
00761     dir_face2 = aBlockTool.GetFaceID(theFace2);
00762   }
00763 
00764   // Find three pairs of points
00765   Standard_Integer v11_id = 0, v12_id = 0, v13_id = 0; // vertices of the first face
00766   Standard_Integer v21_id = 0, v22_id = 0, v23_id = 0; // vertices of the second face
00767 
00768   if (dir_face2 == 2) { // <theFace2> is opposite to <theFace1>
00769 
00770     // We will take vertices with equal local numbers on the faces,
00771     // as the Block6Explorer gives equal local numbers
00772     // to the linked vertices on the opposite faces,
00773     // i.e. v1* is linked with the v2* by an edge:
00774 
00775     //          _________
00776     //        /|v23     /|
00777     //       / |       / |    dir_face1 - bottom
00778     //      /  |      /  |
00779     //     /________ /   |    dir_face2 - top
00780     //    |v21 |    |v22 |
00781     //    |    |____|____|
00782     //    |   / v13 |   /
00783     //    |  /      |  /
00784     //    | /       | /
00785     //    |/________|/
00786     //     v11       v12
00787 
00788     v11_id = aBlockTool.GetVertexID(dir_face1, 1);
00789     v12_id = aBlockTool.GetVertexID(dir_face1, 2);
00790     v13_id = aBlockTool.GetVertexID(dir_face1, 4);
00791 
00792     v21_id = aBlockTool.GetVertexID(dir_face2, 1);
00793     v22_id = aBlockTool.GetVertexID(dir_face2, 2);
00794     v23_id = aBlockTool.GetVertexID(dir_face2, 4);
00795 
00796   } else {
00797 
00798     //          _________
00799     //        /|        /|
00800     //       / |       / |    dir_face1 - bottom
00801     //      /  |      /  |
00802     //     /________ /   |    dir_face2 - right (for example)
00803     //    |    |    |v23 |
00804     //    |    |____|____|
00805     //    |   /     |   /v12 = v22 (common_vertex2)
00806     //    |  /      |  /
00807     //    | /       | /
00808     //    |/________|/
00809     //     v13       v11 = v21 (common_vertex1)
00810 
00811     Standard_Integer common_edge_id = aBlockTool.FindCommonEdgeID(dir_face1, dir_face2);
00812     Standard_Integer common_vertex1 = aBlockTool.GetVertexOnEdgeID(common_edge_id, 1);
00813     Standard_Integer common_vertex2 = aBlockTool.GetVertexOnEdgeID(common_edge_id, 2);
00814 
00815     Standard_Integer not_common_v1 = 0;
00816     Standard_Integer vid = 1;
00817     Standard_Boolean isFound = Standard_False;
00818     while (!isFound && vid <= 4) {
00819       not_common_v1 = aBlockTool.GetVertexID(dir_face1, vid);
00820       isFound = (not_common_v1 != common_vertex2 &&
00821                  aBlockTool.FindEdgeID(not_common_v1, common_vertex1) != 0);
00822       vid++;
00823     }
00824 
00825     Standard_Integer not_common_v2 = 0;
00826     vid = 1;
00827     isFound = Standard_False;
00828     while (!isFound && vid <= 4) {
00829       not_common_v2 = aBlockTool.GetVertexID(dir_face2, vid);
00830       isFound = (not_common_v2 != common_vertex2 &&
00831                  aBlockTool.FindEdgeID(not_common_v2, common_vertex1) != 0);
00832       vid++;
00833     }
00834 
00835     v11_id = common_vertex1;
00836     v12_id = common_vertex2;
00837     v13_id = not_common_v1;
00838 
00839     v21_id = common_vertex1;
00840     v22_id = common_vertex2;
00841     v23_id = not_common_v2;
00842   }
00843 
00844   // Construct a transformation operator
00845   TopoDS_Vertex V11 = TopoDS::Vertex(aBlockTool.GetVertex(v11_id));
00846   TopoDS_Vertex V12 = TopoDS::Vertex(aBlockTool.GetVertex(v12_id));
00847   TopoDS_Vertex V13 = TopoDS::Vertex(aBlockTool.GetVertex(v13_id));
00848 
00849   TopoDS_Vertex V21 = TopoDS::Vertex(aBlockTool.GetVertex(v21_id));
00850   TopoDS_Vertex V22 = TopoDS::Vertex(aBlockTool.GetVertex(v22_id));
00851   TopoDS_Vertex V23 = TopoDS::Vertex(aBlockTool.GetVertex(v23_id));
00852 
00853   // Axes of the first direction face
00854   gp_Pnt P1 = BRep_Tool::Pnt(V11);
00855   gp_Vec VecN1 (P1, BRep_Tool::Pnt(V12));
00856   gp_Vec VecX1 (P1, BRep_Tool::Pnt(V13));
00857   gp_Ax3 Ax1 (P1, VecN1, VecX1);
00858 
00859   // Axes of the second direction face
00860   gp_Pnt P2 = BRep_Tool::Pnt(V21);
00861   gp_Vec VecN2 (P2, BRep_Tool::Pnt(V22));
00862   gp_Vec VecX2 (P2, BRep_Tool::Pnt(V23));
00863   gp_Ax3 Ax2 (P2, VecN2, VecX2);
00864 
00865   gp_Trsf aTrsf;
00866   aTrsf.SetDisplacement(Ax1, Ax2);
00867 
00868   // Check, that <theFace2> is similar to <theFace1>.
00869   // Actually, we need only to check right position of one
00870   // vertex, not involved into the transformation construction.
00871   if (!aBlockTool.IsSimilarFaces(dir_face1, dir_face2, aTrsf)) {
00872     Standard_ConstructionError::Raise("The direction faces are not similar");
00873   }
00874 
00875   // Perform multi-transformation
00876   TopoDS_Compound aCompound;
00877   BRep_Builder B;
00878   B.MakeCompound(aCompound);
00879 
00880   TopoDS_Shape aPrevShape = theBlock;
00881   for (Standard_Integer i = 0; i < theNbIter; i++) {
00882     B.Add(aCompound, aPrevShape);
00883     BRepBuilderAPI_Transform aTransformation (aPrevShape, aTrsf, Standard_False);
00884     aPrevShape = aTransformation.Shape();
00885   }
00886   theResult = aCompound;
00887 }
00888 
00889 //=======================================================================
00890 //function :  MultiTransformate2D
00891 //purpose  :
00892 //=======================================================================
00893 void GEOMImpl_BlockDriver::MultiTransformate2D (const TopoDS_Shape&    theBlock,
00894                                                 const TopoDS_Shape&    theFace1U,
00895                                                 const TopoDS_Shape&    theFace2U,
00896                                                 const Standard_Integer theNbIterU,
00897                                                 const TopoDS_Shape&    theFace1V,
00898                                                 const TopoDS_Shape&    theFace2V,
00899                                                 const Standard_Integer theNbIterV,
00900                                                 TopoDS_Shape&          theResult) const
00901 {
00902   // Construct Tool, where <theFace1U> will be the first face,
00903   // and a face, opposite to <theFace1U>, will be the second face
00904   GEOMImpl_Block6Explorer aBlockTool;
00905   aBlockTool.InitByBlockAndFace(theBlock, theFace1U);
00906 
00907   gp_Trsf aTrsfU, aTrsfV;
00908   gp_Ax3 Ax1V, Ax2V;
00909   for (Standard_Integer uv = 1; uv <= 2; uv++) {
00910     // U transformation
00911     TopoDS_Shape theFace1 = theFace1U;
00912     TopoDS_Shape theFace2 = theFace2U;
00913     if (uv == 2) {
00914       // V transformation
00915       theFace1 = theFace1V;
00916       theFace2 = theFace2V;
00917     }
00918 
00919     // Find IDs of the faces
00920     Standard_Integer dir_face1 = aBlockTool.GetFaceID(theFace1);
00921     Standard_Integer dir_face2 = 0;
00922     Standard_Integer opp_face1 = aBlockTool.GetOppositeFaceID(dir_face1);
00923     if (theFace2.IsNull()) {
00924       dir_face2 = opp_face1;
00925     } else {
00926       dir_face2 = aBlockTool.GetFaceID(theFace2);
00927     }
00928 
00929     // Find three pairs of points
00930     Standard_Integer v11_id = 0, v12_id = 0, v13_id = 0; // vertices of the first face
00931     Standard_Integer v21_id = 0, v22_id = 0, v23_id = 0; // vertices of the second face
00932 
00933     if (dir_face2 == opp_face1) { // <theFace2> is opposite to <theFace1>
00934 
00935       // We will take vertices with equal local numbers on the faces,
00936       // as the Block6Explorer gives equal local numbers
00937       // to the linked vertices on the opposite faces,
00938       // i.e. v1* is linked with the v2* by an edge:
00939 
00940       v11_id = aBlockTool.GetVertexID(dir_face1, 1);
00941       v12_id = aBlockTool.GetVertexID(dir_face1, 2);
00942       v13_id = aBlockTool.GetVertexID(dir_face1, 4);
00943 
00944       v21_id = aBlockTool.GetVertexID(dir_face2, 1);
00945       v22_id = aBlockTool.GetVertexID(dir_face2, 2);
00946       v23_id = aBlockTool.GetVertexID(dir_face2, 4);
00947 
00948     } else {
00949 
00950       Standard_Integer common_edge_id = aBlockTool.FindCommonEdgeID(dir_face1, dir_face2);
00951       Standard_Integer common_vertex1 = aBlockTool.GetVertexOnEdgeID(common_edge_id, 1);
00952       Standard_Integer common_vertex2 = aBlockTool.GetVertexOnEdgeID(common_edge_id, 2);
00953 
00954       Standard_Integer not_common_v1 = 0;
00955       Standard_Integer vid = 1;
00956       Standard_Boolean isFound = Standard_False;
00957       while (!isFound && vid <= 4) {
00958         not_common_v1 = aBlockTool.GetVertexID(dir_face1, vid);
00959         isFound = (not_common_v1 != common_vertex2 &&
00960                    aBlockTool.FindEdgeID(not_common_v1, common_vertex1) != 0);
00961         vid++;
00962       }
00963 
00964       Standard_Integer not_common_v2 = 0;
00965       vid = 1;
00966       isFound = Standard_False;
00967       while (!isFound && vid <= 4) {
00968         not_common_v2 = aBlockTool.GetVertexID(dir_face2, vid);
00969         isFound = (not_common_v2 != common_vertex2 &&
00970                    aBlockTool.FindEdgeID(not_common_v2, common_vertex1) != 0);
00971         vid++;
00972       }
00973 
00974       v11_id = common_vertex1;
00975       v12_id = common_vertex2;
00976       v13_id = not_common_v1;
00977 
00978       v21_id = common_vertex1;
00979       v22_id = common_vertex2;
00980       v23_id = not_common_v2;
00981     }
00982 
00983     // Construct a transformation operator
00984     TopoDS_Vertex V11 = TopoDS::Vertex(aBlockTool.GetVertex(v11_id));
00985     TopoDS_Vertex V12 = TopoDS::Vertex(aBlockTool.GetVertex(v12_id));
00986     TopoDS_Vertex V13 = TopoDS::Vertex(aBlockTool.GetVertex(v13_id));
00987 
00988     TopoDS_Vertex V21 = TopoDS::Vertex(aBlockTool.GetVertex(v21_id));
00989     TopoDS_Vertex V22 = TopoDS::Vertex(aBlockTool.GetVertex(v22_id));
00990     TopoDS_Vertex V23 = TopoDS::Vertex(aBlockTool.GetVertex(v23_id));
00991 
00992     // Axes of the first direction face
00993     gp_Pnt P1 = BRep_Tool::Pnt(V11);
00994     gp_Vec VecN1 (P1, BRep_Tool::Pnt(V12));
00995     gp_Vec VecX1 (P1, BRep_Tool::Pnt(V13));
00996     gp_Ax3 Ax1 (P1, VecN1, VecX1);
00997 
00998     // Axes of the second direction face
00999     gp_Pnt P2 = BRep_Tool::Pnt(V21);
01000     gp_Vec VecN2 (P2, BRep_Tool::Pnt(V22));
01001     gp_Vec VecX2 (P2, BRep_Tool::Pnt(V23));
01002     gp_Ax3 Ax2 (P2, VecN2, VecX2);
01003 
01004     gp_Trsf aTrsf;
01005     aTrsf.SetDisplacement(Ax1, Ax2);
01006     if (uv == 1) {
01007       aTrsfU = aTrsf;
01008     } else {
01009       aTrsfV = aTrsf;
01010       Ax1V = Ax1;
01011       Ax2V = Ax2;
01012     }
01013 
01014     // Check, that <theFace2> is similar to <theFace1>.
01015     // Actually, we need only to check right position of one
01016     // vertex, not involved into the transformation construction.
01017     if (!aBlockTool.IsSimilarFaces(dir_face1, dir_face2, aTrsf)) {
01018       Standard_ConstructionError::Raise("The direction faces are not similar");
01019     }
01020   }
01021 
01022   // Perform multi-transformation
01023   TopoDS_Compound aCompound;
01024   BRep_Builder B;
01025   B.MakeCompound(aCompound);
01026 
01027   TopoDS_Shape aPrevShapeU = theBlock;
01028   for (int i = 0; i < theNbIterU; i++) {
01029     TopoDS_Shape aPrevShapeV = aPrevShapeU;
01030     for (int j = 0; j < theNbIterV; j++) {
01031       B.Add(aCompound, aPrevShapeV);
01032       BRepBuilderAPI_Transform aTransformationV (aPrevShapeV, aTrsfV, Standard_False);
01033       aPrevShapeV = aTransformationV.Shape();
01034     }
01035     BRepBuilderAPI_Transform aTransformationU (aPrevShapeU, aTrsfU, Standard_False);
01036     aPrevShapeU = aTransformationU.Shape();
01037     // Correction of the second transformation according to the first transformation
01038     Ax1V.Transform(aTrsfU);
01039     Ax2V.Transform(aTrsfU);
01040     aTrsfV.SetDisplacement(Ax1V, Ax2V);
01041     // Correction done
01042   }
01043   theResult = aCompound;
01044 }
01045 
01046 //=======================================================================
01047 //function :  GEOMImpl_BlockDriver_Type_
01048 //purpose  :
01049 //=======================================================================
01050 Standard_EXPORT Handle_Standard_Type& GEOMImpl_BlockDriver_Type_()
01051 {
01052 
01053   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
01054   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
01055   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
01056   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
01057   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
01058   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
01059 
01060 
01061   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
01062   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_BlockDriver",
01063                                                          sizeof(GEOMImpl_BlockDriver),
01064                                                          1,
01065                                                          (Standard_Address)_Ancestors,
01066                                                          (Standard_Address)NULL);
01067 
01068   return _aType;
01069 }
01070 
01071 //=======================================================================
01072 //function : DownCast
01073 //purpose  :
01074 //=======================================================================
01075 const Handle(GEOMImpl_BlockDriver) Handle(GEOMImpl_BlockDriver)::DownCast
01076   (const Handle(Standard_Transient)& AnObject)
01077 {
01078   Handle(GEOMImpl_BlockDriver) _anOtherObject;
01079 
01080   if (!AnObject.IsNull()) {
01081      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_BlockDriver))) {
01082        _anOtherObject = Handle(GEOMImpl_BlockDriver)((Handle(GEOMImpl_BlockDriver)&)AnObject);
01083      }
01084   }
01085 
01086   return _anOtherObject;
01087 }