]> OCCT Git - occt-copy.git/commitdiff
0029692: Add functionality to make the group of touching same-dimensional shapes... CR0-720-FixAS
authoremv <emv@opencascade.com>
Thu, 12 Apr 2018 13:22:34 +0000 (16:22 +0300)
committeremv <emv@opencascade.com>
Fri, 13 Apr 2018 08:25:57 +0000 (11:25 +0300)
Implementation of the new class *BOPAlgo_MakeConnected* for making the group of touching same-dimensional shapes connected.
Provide the material association for the first sub-elements of the input shapes.
Provide possibility to make the connected shape periodic.

Draw commands for new algorithm:
* makeconnected - make the input shapes connected or glued, performs material associations;
* cmaterialson - returns the materials located on the requested side of a shape;
* cmakeperiodic - makes the connected shape periodic in requested directions;
* crepeatshape - repeats the periodic connected shape in requested directions requested number of times.

Documentation & test cases for the new algorithm.

15 files changed:
dox/user_guides/draw_test_harness/draw_test_harness.md
dox/user_guides/modeling_algos/modeling_algos.md
src/BOPAlgo/BOPAlgo.msg
src/BOPAlgo/BOPAlgo_Alerts.hxx
src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
src/BOPAlgo/BOPAlgo_MakeConnected.cxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_MakeConnected.hxx [new file with mode: 0644]
src/BOPAlgo/FILES
src/BOPTest/BOPTest.cxx
src/BOPTest/BOPTest.hxx
src/BOPTest/BOPTest_MkConnectedCommands.cxx [new file with mode: 0644]
src/BOPTest/FILES
tests/boolean/grids.list
tests/boolean/mkconnected/A1 [new file with mode: 0644]
tests/boolean/mkconnected/A2 [new file with mode: 0644]

index bd186013c3a959e3e67a2a6a98a4113145d4edd2..545d33f594ee8e43a4b7011e58e19989cdbeea5e 100644 (file)
@@ -5823,6 +5823,7 @@ The following topics are covered in the eight sections of this chapter:
   * Drafting and blending.
   * Defeaturing.
   * Making shapes periodic in 3D space.
+  * Making shapes connected.
   * Analysis of shapes.
 
 
@@ -7380,6 +7381,73 @@ The command clears all previous repetitions of the periodic shape allowing to st
 No arguments are needed for the command.
 
 
+@subsection occt_draw_makeconnected Making the touching shapes connected
+
+Draw module for @ref occt_modalg_makeconnected "making the touching same-dimensional shapes connected" includes the following commands:
+* **makeconnected** - make the input shapes connected or glued, performs material associations;
+* **cmaterialson** - returns the materials located on the requested side of a shape;
+* **cmakeperiodic** - makes the connected shape periodic in requested directions;
+* **crepeatshape** - repeats the periodic connected shape in requested directions requested number of times.
+
+@subsubsection occt_draw_makeconnected_makeconnected makeconnected
+
+The command makes the input touching shapes connected.
+
+Syntax:
+~~~~
+makeconnected result shape1 shape2 ...
+
+Where:
+result            - resulting connected shape.
+shape1 shape2 ... - shapes to be made connected.
+~~~~
+
+@subsubsection occt_draw_makeconnected_cmaterialson cmaterialson
+
+The command returns the materials located on the requested side of the shape.
+The command should be called after the shapes have been made connected, i.e. after the command **makeconnected**.
+
+Syntax:
+~~~~
+cmaterialson result +/- shape
+
+Where:
+result - material shapes
+shape  - shape for which the materials are needed
++/-    - side of a given shape ('+' for positive side, '-' - for negative).
+~~~~
+
+@subsubsection occt_draw_makeconnected_cmakeperiodic cmakeperiodic
+
+The command makes the connected shape periodic in the required directions with the required period.
+The command should be called after the shapes have been made connected, i.e. after the command **makeconnected**.
+
+Syntax:
+~~~~
+cmakeperiodic result [-x/y/z period [-trim first]]
+Where:
+result        - resulting periodic shape;
+shape         - input shape to make it periodic:
+-x/y/z period - option to make the shape periodic in X, Y or Z direction with the given period;
+-trim first   - option to trim the shape to fit the required period, starting the period in first.
+~~~~
+
+@subsubsection occt_draw_makeconnected_crepeatshape crepeatshape
+
+The command repeats the connected periodic shape in the required periodic directions required number of times.
+The command should be called after the shapes have been made connected and periodic, i.e. after the commands **makeconnected** and **cmakeperiodic**.
+
+Syntax:
+~~~~
+crepeatshape result -x/y/z times
+
+Where:
+result       - resulting shape;
+-x/y/z times - direction for repetition and number of repetitions (negative number of times means the repetition in negative direction).
+~~~~
+
+
 @subsection occt_draw_7_9  Analysis of topology and geometry
 
 Analysis of shapes includes commands to compute length, area, volumes and inertial properties, as well as to compute some aspects impacting shape validity.
index cc515d15ce00a4dcf40adb8f1fd3a6cba2f2b6ae..ef24005c61ee59f984f2d313c3b54eadfee78486 100644 (file)
@@ -3482,3 +3482,145 @@ repeatshape drills -x 24 -y 24
 bcut result plate drills
 ~~~~
 @figure{/user_guides/modeling_algos/images/modeling_algos_mkperiodic_im006.png,"Plate with drills",220}
+
+
+@section occt_modalg_makeconnected Making touching shapes connected
+
+Open CASCADE Technology provides tools for making the same-dimensional touching shapes connected (or glued), i.e. for making the coinciding geometries topologically shared among shapes.
+To make the shapes connected they are glued by the means of @ref occt_algorithms_7 "General Fuse algorithm". The option BOPAlgo_GlueShift is used, thus if the input shapes have been interfering the algorithm will be unable to recognize this.
+
+Making the group of shapes connected can be a useful e.g. before meshing the group. It will allow making the resulting mesh conformal.
+
+The algorithm for making the shapes connected is is implemented in the class *BOPAlgo_MakeConnected*.
+
+@subsection occt_modalg_makeconnected_materials Material association
+
+In frames of this tool the input shapes are called materials, and each input shape has a unique material.
+
+After making the shapes connected, the first sub-elements of the input shapes are associated with the shapes to which the belong. At that, the orientation of the sub-elements in the shape is taken into account.
+The associations are made for the following types:
+* For input SOLIDS the resulting FACES are associated with the input solids;
+* For input FACES the resulting EDGES are associated with the input faces;
+* For input EDGES the resulting VERTICES are associated with the input edges.
+The association process is called the material association. It allows finding the coinciding elements for the opposite input shapes. These elements will be associated to at least two materials (one on the positive side of the shape, the other - on negative).
+
+For obtaining the material information the following methods should be used
+* *MaterialsOnPositiveSide()* - returns the original shapes (materials) located on the positive side of the given shape (i.e. with FORWARD orientation);
+* *MaterialsOnNegativeSide()* - returns the original shapes (materials) located on the negative side of the given shape (i.e. with REVERSED orientation);
+
+~~~~
+// Returns the original shapes which images contain the given shape with FORWARD orientation.
+const TopTools_ListOfShape& BOPAlgo_MakeConnected::MaterialsOnPositiveSide(const TopoDS_Shape& theS)
+
+// Returns the original shapes which images contain the given shape with REVERSED orientation.
+const TopTools_ListOfShape& BOPAlgo_MakeConnected::MaterialsOnNegativeSide(const TopoDS_Shape& theS)
+~~~~
+
+@subsection occt_modalg_makeconnected_makeperiodic Making connected shape periodic
+
+The tool provides possibility to make the connected shape @ref occt_modalg_makeperiodic "periodic".
+Since by making the shape periodic it ensures that the geometry of coinciding shapes on the opposite sides will be the same it allows reusing the mesh of the shape for its periodic twins.
+
+After making the shape periodic the material associations are updated to correspond to the actual state of the result shape. Repetition of the periodic shape is also possible from here. Material associations are not going to be lost.
+
+@subsection occt_modalg_makeconnected_history History support
+
+The algorithm supports history of shapes modifications during the operation. Additionally to standard history method provided by *BRepTools_History* and used here as a history tool, the algorithm also provides the method to track the back connection - from resulting shapes to the input ones.
+The method is called *GetOrigins()*:
+~~~~
+// Returns the list of original shapes from which the current shape has been created.
+const TopTools_ListOfShape& BOPAlgo_MakeConnected::GetOrigins(const TopoDS_Shape& theS);
+~~~~
+
+Both Gluing history and history of making the shape periodic and periodic shape repetition are available here. Note, that all repeated shapes are stored as generated into the history.
+
+@subsection occt_modalg_makeconnected_errors Errors/Warnings
+
+The algorithm supports the Error/Warning reporting system which allows obtaining the extended overview of the errors and warning occurred during the operation.
+As soon as any error appears the algorithm stops working. The warnings allow continuing the job, informing the user that something went wrong.
+The algorithm returns the following alerts:
+* *BOPAlgo_AlertTooFewArguments* - error alert is given on the attempt to run the algorithm without the arguments;
+* *BOPAlgo_AlertMultiDimensionalArguments* - error alert is given on the attempt to run the algorithm on multi-dimensional arguments;
+* *BOPAlgo_AlertUnableToGlue* - error alert is given if the gluer algorithm is unable to glue the given arguments;
+* *BOPAlgo_AlertUnableToMakePeriodic* - warning alert is given if the periodicity maker is unable to make the connected shape periodic with given options;
+* *BOPAlgo_AlertShapeIsNotPeriodic* - warning alert is given on the attempt to repeat the shape before making it periodic.
+
+For more information on the error/warning reporting system please see the chapter @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide.
+
+@subsection occt_modalg_makeconnected_usage Usage
+
+Here is the example of usage of the *BOPAlgo_MakePeriodic* algorithm on the API level:
+~~~~
+TopTools_ListOfShape anArguments = ...;  // Shapes to make connected
+Standard_Boolean bRunParallel = ...;     // Parallel processing mode
+
+BOPAlgo_MakeConnected aMC;               // Tool for making the shapes connected
+aMC.SetArguments(anArguments);           // Set the shapes
+aMC.SetRunParallel(bRunParallel);        // Set parallel processing mode
+aMC.Perform();                           // Perform the operation
+
+if (aMC.HasErrors())                     // Check for the errors
+{
+  // errors treatment
+  Standard_SStream aSStream;
+  aMC.DumpErrors(aSStream);
+  return;
+}
+if (aMC.HasWarnings())                   // Check for the warnings
+{
+  // warnings treatment
+  Standard_SStream aSStream;
+  aMC.DumpWarnings(aSStream);
+}
+
+const TopoDS_Shape& aGluedShape = aMC.Shape(); // Connected shape
+
+// Checking material associations
+TopAbs_ShapeEnum anElemType = ...;       // Type of first BRep sub-element
+TopExp_Explorer anExp(anArguments.First(), anElemType);
+for (; anExp.More(); anExp.Next())
+{
+  const TopoDS_Shape& anElement = anExp.Current();
+  const TopTools_ListOfShape& aNegativeM = aMC.MaterialsOnNegativeSide(anElement);
+  const TopTools_ListOfShape& aPositiveM = aMC.MaterialsOnPositiveSide(anElement);
+}
+
+// Making the connected shape periodic
+BOPAlgo_MakePeriodic::PeriodicityParams aParams = ...; // Options for periodicity of the connected shape
+aMC.MakePeriodic(aParams);
+
+// Shape repetition after making it periodic
+// Check if the shape has been made periodic successfully
+if (aMC.PeriodicityTool().HasErrors())
+{
+  // Periodicity maker error treatment
+}
+
+// Shape repetition in periodic directions
+aMC.RepeatShape(0, 2);
+
+const TopoDS_Shape& aShape = aMC.PeriodicShape(); // Periodic and repeated shape
+~~~~
+
+Please note, that the class is based on the options class *BOPAlgo_Options*, which provides the following options for the algorithm:
+* Error/Warning reporting system;
+* Parallel processing mode.
+The other options of the base class are not supported here and will have no effect.
+
+All the history information obtained during the operation is stored into *BRepTools_History* object and available through *History()* method:
+~~~~
+// Get the history object
+const Handle(BRepTools_History)& BOPAlgo_MakeConnected::History();
+~~~~
+
+For the usage of the MakeConnected algorithm on the Draw level the following commands have been implemented:
+* **makeconnected**
+* **cmaterialson**
+* **cmakeperiodic**
+* **crepeatshape**
+
+For more details on the connexity commands please refer the @ref occt_draw_makeconnected "MakeConnected commands" of the Draw test harness user guide.
+
+To track the history of a shape modification during MakeConnected operation the @ref occt_draw_hist "standard history commands" can be used.
+
+To have possibility to access the error/warning shapes of the operation use the *bdrawwarnshapes* command before running the algorithm (see command usage in the @ref occt_algorithms_ers "Errors and warnings reporting system" of Boolean operations user guide).
index b170ad4aae9e3351e17dcde043dc39014c09d10b..645fd17cc06cb450a3c526e819f466dc09f59ce2 100644 (file)
@@ -102,4 +102,16 @@ Error: Unable to trim the shape for making it periodic (BOP Common fails)
 Error: Unable to make the shape to look identical on opposite sides (Splitter fails)
 
 .BOPAlgo_AlertUnableToRepeat
-Error: Unable to repeat the shape (Gluer fails)
\ No newline at end of file
+Error: Unable to repeat the shape (Gluer fails)
+
+.BOPAlgo_AlertMultiDimensionalArguments
+Error: Multi-dimensional arguments
+
+.BOPAlgo_AlertUnableToMakePeriodic
+Warning: Unable to make the shape periodic
+
+.BOPAlgo_AlertUnableToGlue
+Error: Unable to glue the shapes
+
+.BOPAlgo_AlertShapeIsNotPeriodic
+Warning: The shape is not periodic
\ No newline at end of file
index eb2162b413dc572ef297f46f51ed9ce263822c33..ba3604c12d4632b3d16605cf3b4043c01cc172de 100644 (file)
@@ -116,4 +116,16 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToMakeIdentical)
 //! Unable to repeat the shape (Gluer fails)
 DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToRepeat)
 
+//! Multi-dimensional arguments
+DEFINE_SIMPLE_ALERT(BOPAlgo_AlertMultiDimensionalArguments)
+
+//! Unable to make the shape periodic
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToMakePeriodic)
+
+//! Unable to glue the shapes
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToGlue)
+
+//! The shape is not periodic
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShapeIsNotPeriodic)
+
 #endif // _BOPAlgo_Alerts_HeaderFile
index f0dfbdaacb7693e7611c60c4745cd45798fdcebf..58e4c133fb54f9ea11e80d67f9cf0b410065a188 100644 (file)
@@ -105,4 +105,16 @@ static const char BOPAlgo_BOPAlgo_msg[] =
   "Error: Unable to make the shape to look identical on opposite sides (Splitter fails)\n"
   "\n"
   ".BOPAlgo_AlertUnableToRepeat\n"
-  "Error: Unable to repeat the shape (Gluer fails)\n";
+  "Error: Unable to repeat the shape (Gluer fails)\n"
+  "\n"
+  ".BOPAlgo_AlertMultiDimensionalArguments\n"
+  "Error: Multi-dimensional arguments\n"
+  "\n"
+  ".BOPAlgo_AlertUnableToMakePeriodic\n"
+  "Warning: Unable to make the shape periodic\n"
+  "\n"
+  ".BOPAlgo_AlertUnableToGlue\n"
+  "Error: Unable to glue the shapes\n"
+  "\n"
+  ".BOPAlgo_AlertShapeIsNotPeriodic\n"
+  "Warning: The shape is not periodic\n";
diff --git a/src/BOPAlgo/BOPAlgo_MakeConnected.cxx b/src/BOPAlgo/BOPAlgo_MakeConnected.cxx
new file mode 100644 (file)
index 0000000..a870f95
--- /dev/null
@@ -0,0 +1,305 @@
+// Created on: 2018-03-29
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BOPAlgo_MakeConnected.hxx>
+
+#include <BOPAlgo_Alerts.hxx>
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_Tools.hxx>
+
+#include <BOPTools_AlgoTools.hxx>
+
+#include <BRep_Builder.hxx>
+
+#include <TopExp_Explorer.hxx>
+
+#include <TopoDS_Iterator.hxx>
+
+//=======================================================================
+//function : Perform
+//purpose  : Makes the shapes connected
+//=======================================================================
+void BOPAlgo_MakeConnected::Perform()
+{
+  // Check the input data
+  CheckData();
+  if (HasErrors())
+    return;
+
+  if (myHistory.IsNull())
+    myHistory = new BRepTools_History;
+
+  // Glue the arguments
+  MakeConnected();
+  if (HasErrors())
+    return;
+
+  // Perform material associations for the faces
+  AssociateMaterials();
+  if (HasErrors())
+    return;
+}
+
+//=======================================================================
+//function : CheckData
+//purpose  : Check the validity of input data
+//=======================================================================
+void BOPAlgo_MakeConnected::CheckData()
+{
+  // Check the number of arguments
+  if (myArguments.IsEmpty())
+  {
+    // Not enough arguments
+    AddError(new BOPAlgo_AlertTooFewArguments());
+    return;
+  }
+
+  // Check that all shapes in arguments are of the same type
+
+  // Extract the shapes from the compound arguments
+  TopTools_ListOfShape aLA;
+  // Fence map
+  TopTools_MapOfShape aMFence;
+
+  TopTools_ListIteratorOfListOfShape itLA(myArguments);
+  for (; itLA.More(); itLA.Next())
+    BOPAlgo_Tools::TreatCompound(itLA.Value(), aMFence, aLA);
+
+  if (aLA.IsEmpty())
+  {
+    // It seems that all argument shapes are empty compounds
+    AddError(new BOPAlgo_AlertTooFewArguments());
+    return;
+  }
+
+  // Check dimensions of the extracted non-compound shapes
+  itLA.Initialize(aLA);
+  Standard_Integer iDim = BOPTools_AlgoTools::Dimension(itLA.Value());
+  for (itLA.Next(); itLA.More(); itLA.Next())
+  {
+    if (iDim != BOPTools_AlgoTools::Dimension(itLA.Value()))
+    {
+      // The arguments are of different type
+      AddError(new BOPAlgo_AlertMultiDimensionalArguments());
+      return;
+    }
+  }
+}
+
+//=======================================================================
+//function : MakeConnected
+//purpose  : Glues the argument shapes
+//=======================================================================
+void BOPAlgo_MakeConnected::MakeConnected()
+{
+  // Initialize the history
+  if (myGlueHistory.IsNull())
+    myGlueHistory = new BRepTools_History;
+
+  if (myArguments.Extent() == 1)
+  {
+    // No need to glue the single shape
+    myShape = myArguments.First();
+  }
+  else
+  {
+    // Glue the shapes
+    BOPAlgo_Builder aGluer;
+    aGluer.SetArguments(myArguments);
+    aGluer.SetGlue(BOPAlgo_GlueShift);
+    aGluer.SetRunParallel(myRunParallel);
+    aGluer.SetNonDestructive(Standard_True);
+    aGluer.Perform();
+    if (aGluer.HasErrors())
+    {
+      // Unable to glue the shapes
+      TopoDS_Compound aCW;
+      BRep_Builder().MakeCompound(aCW);
+      for (TopTools_ListIteratorOfListOfShape it(myArguments); it.More(); it.Next())
+        BRep_Builder().Add(aCW, it.Value());
+      AddError(new BOPAlgo_AlertUnableToGlue(aCW));
+      return;
+    }
+    myShape = aGluer.Shape();
+    // Save the gluing history
+    myGlueHistory->Merge(aGluer.Arguments(), aGluer);
+    myHistory->Merge(myGlueHistory);
+  }
+
+  // Keep the glued shape
+  myGlued = myShape;
+
+  // Fill the map of origins
+  FillOrigins();
+}
+
+//=======================================================================
+//function : FillOrigins
+//purpose  : Fills the map of origins
+//=======================================================================
+void BOPAlgo_MakeConnected::FillOrigins()
+{
+  myOrigins.Clear();
+
+  // Map the history shapes of the arguments
+  if (myAllInputsMap.IsEmpty())
+  {
+    TopTools_ListIteratorOfListOfShape itLA(myArguments);
+    for (; itLA.More(); itLA.Next())
+      TopExp::MapShapes(itLA.Value(), myAllInputsMap);
+  }
+
+  const Standard_Integer aNbS = myAllInputsMap.Extent();
+  for (Standard_Integer i = 1; i <= aNbS; ++i)
+  {
+    const TopoDS_Shape& aS = myAllInputsMap(i);
+    if (!BRepTools_History::IsSupportedType(aS))
+      continue;
+
+    // Get Modified & Generated shapes
+    for (Standard_Integer j = 0; j < 2; ++j)
+    {
+      const TopTools_ListOfShape& aLH = !j ? myHistory->Modified(aS) : myHistory->Generated(aS);
+      TopTools_ListIteratorOfListOfShape itLH(aLH);
+      for (; itLH.More(); itLH.Next())
+      {
+        const TopoDS_Shape& aHS = itLH.Value();
+        TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aHS);
+        if (!pLOr)
+          pLOr = myOrigins.Bound(aHS, TopTools_ListOfShape());
+        if (!pLOr->Contains(aS))
+          pLOr->Append(aS);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : AssociateMaterials
+//purpose  : Associates the materials for the first BRep sub-elements
+//=======================================================================
+void BOPAlgo_MakeConnected::AssociateMaterials()
+{
+  myMaterials.Clear();
+
+  // Extract all non-compound shapes from the result
+  TopTools_ListOfShape aLShapes;
+  TopTools_MapOfShape aMFence;
+  BOPAlgo_Tools::TreatCompound(myShape, aMFence, aLShapes);
+
+  if (aLShapes.IsEmpty())
+    return;
+
+  // Define the element type and the material type
+  TopAbs_ShapeEnum anElemType;
+  const TopAbs_ShapeEnum aMaterialType = aLShapes.First().ShapeType();
+  if (aMaterialType == TopAbs_SOLID || aMaterialType == TopAbs_COMPSOLID)
+    anElemType = TopAbs_FACE;
+  else if (aMaterialType == TopAbs_FACE || aMaterialType == TopAbs_SHELL)
+    anElemType = TopAbs_EDGE;
+  else if (aMaterialType == TopAbs_EDGE || aMaterialType == TopAbs_WIRE)
+    anElemType = TopAbs_VERTEX;
+  else
+    return;
+
+  TopTools_ListIteratorOfListOfShape itLS(aLShapes);
+  for (; itLS.More(); itLS.Next())
+  {
+    const TopoDS_Shape& aS = itLS.Value();
+    const TopTools_ListOfShape& aLOr = GetOrigins(aS);
+    const TopoDS_Shape& aSOr = aLOr.IsEmpty() ? aS : aLOr.First();
+
+    TopExp_Explorer anExp(aS, anElemType);
+    for (; anExp.More(); anExp.Next())
+    {
+      const TopoDS_Shape& anElement = anExp.Current();
+      TopTools_ListOfShape* pLM = myMaterials.ChangeSeek(anElement);
+      if (!pLM)
+        pLM = myMaterials.Bound(anElement, TopTools_ListOfShape());
+      pLM->Append(aSOr);
+    }
+  }
+}
+
+//=======================================================================
+//function : MakePeriodic
+//purpose  : Makes the shape periodic according to the given parameters
+//=======================================================================
+void BOPAlgo_MakeConnected::MakePeriodic(const BOPAlgo_MakePeriodic::PeriodicityParams& theParams)
+{
+  if (HasErrors())
+    return;
+
+  // Make the shape periodic
+  myPeriodicityMaker.Clear();
+  myPeriodicityMaker.SetShape(myGlued);
+  myPeriodicityMaker.SetPeriodicityParameters(theParams);
+  myPeriodicityMaker.SetRunParallel(myRunParallel);
+  myPeriodicityMaker.Perform();
+  if (myPeriodicityMaker.HasErrors())
+  {
+    // Add warning informing the user that periodicity with
+    // given parameters is not possible
+    AddWarning(new BOPAlgo_AlertUnableToMakePeriodic(myShape));
+    return;
+  }
+
+  myShape = myPeriodicityMaker.Shape();
+
+  // Update history
+  myHistory->Clear();
+  if (!myGlueHistory.IsNull())
+    myHistory->Merge(myGlueHistory);
+  myHistory->Merge(myPeriodicityMaker.History());
+
+  // Fill the map of origins
+  FillOrigins();
+
+  // Update the material associations after making the shape periodic
+  AssociateMaterials();
+}
+
+//=======================================================================
+//function : RepeatShape
+//purpose  : Repeats the shape in the given direction given number of times
+//=======================================================================
+void BOPAlgo_MakeConnected::RepeatShape(const Standard_Integer theDirectionID,
+                                        const Standard_Integer theTimes)
+{
+  if (HasErrors())
+    return;
+
+  if (myPeriodicityMaker.Shape().IsNull() || myPeriodicityMaker.HasErrors())
+  {
+    // The shape has not been made periodic yet
+    AddWarning(new BOPAlgo_AlertShapeIsNotPeriodic(myShape));
+    return;
+  }
+
+  // Repeat the shape
+  myShape = myPeriodicityMaker.RepeatShape(theDirectionID, theTimes);
+
+  // Update history
+  myHistory->Clear();
+  if (!myGlueHistory.IsNull())
+    myHistory->Merge(myGlueHistory);
+  myHistory->Merge(myPeriodicityMaker.History());
+
+  // Fill the map of origins
+  FillOrigins();
+
+  // Update the material associations after shape repetitions
+  AssociateMaterials();
+}
diff --git a/src/BOPAlgo/BOPAlgo_MakeConnected.hxx b/src/BOPAlgo/BOPAlgo_MakeConnected.hxx
new file mode 100644 (file)
index 0000000..59f914c
--- /dev/null
@@ -0,0 +1,330 @@
+// Created on: 2018-03-29
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BOPAlgo_MakeConnected_HeaderFile
+#define _BOPAlgo_MakeConnected_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <BOPAlgo_Options.hxx>
+#include <BOPAlgo_MakePeriodic.hxx>
+
+#include <BRepTools_History.hxx>
+
+#include <NCollection_DataMap.hxx>
+
+#include <TopTools_OrientedShapeMapHasher.hxx>
+
+//! BOPAlgo_MakeConnected is the algorithm for making the touching
+//! shapes connected or glued, i.e. for making the coinciding geometries
+//! be topologically shared among the shapes.
+//!
+//! The input shapes should be of the same dimension, otherwise
+//! the gluing will not make any sense.
+//!
+//! After the shapes are made connected, the first sub-elements of input shapes
+//! are associated with the shapes to which they belong. At that, the orientation of
+//! the sub-element in the shape is taken into account.
+//! The associations are made for the following types:
+//! - For input SOLIDS, the resulting FACES are associated with the input solids;
+//! - For input FACES, the resulting EDGES are associated with the input faces;
+//! - For input EDGES, the resulting VERTICES are associated with the input edges.
+//!
+//! In frames of this algorithm the input shapes are called materials,
+//! and the association process is called the material association.
+//! The material association allows finding the coinciding elements for the opposite
+//! input shapes. These elements will be associated to at least two materials.
+//!
+//! After making the shapes connected, it is possible to make the connected
+//! shape periodic using the *BOPAlgo_MakePeriodic* tool.
+//! After making the shape periodic, the material associations will be updated
+//! to correspond to the actual state of the result shape.
+//! Repetition of the periodic shape is also possible here. Material associations
+//! are not going to be lost.
+//!
+//! The algorithm supports history of shapes modification, thus it is possible
+//! to track the modification of the input shapes during the operations.
+//! Additionally to standard history methods, the algorithm provides the
+//! the method *GetOrigins()* which allows obtaining the input shapes from which
+//! the resulting shape has been created.
+//!
+//! The algorithm supports the parallel processing mode, which allows faster
+//! completion of the operations.
+//!
+//! The algorithm returns the following Error/Warning messages:
+//! - *BOPAlgo_AlertTooFewArguments* - error alert is given on the attempt to run
+//!     the algorithm without the arguments;
+//! - *BOPAlgo_AlertMultiDimensionalArguments* - error alert is given on the attempt
+//!     to run the algorithm on multi-dimensional arguments;
+//! - *BOPAlgo_AlertUnableToGlue* - error alert is given if the gluer algorithm
+//!     is unable to glue the given arguments;
+//! - *BOPAlgo_AlertUnableToMakePeriodic* - warning alert is given if the periodicity
+//!     maker is unable to make the connected shape periodic with given options;
+//! - *BOPAlgo_AlertShapeIsNotPeriodic* - warning alert is given on the attempt to
+//!     repeat the shape before making it periodic.
+//!
+//! Here is the example of usage of the algorithm:
+//! ~~~~
+//! TopTools_ListOfShape anArguments = ...;  // Shapes to make connected
+//! Standard_Boolean bRunParallel = ...;     // Parallel processing mode
+//!
+//! BOPAlgo_MakeConnected aMC;               // Tool for making the shapes connected
+//! aMC.SetArguments(anArguments);           // Set the shapes
+//! aMC.SetRunParallel(bRunParallel);        // Set parallel processing mode
+//! aMC.Perform();                           // Perform the operation
+//!
+//! if (aMC.HasErrors())                     // Check for the errors
+//! {
+//!   // errors treatment
+//!   Standard_SStream aSStream;
+//!   aMC.DumpErrors(aSStream);
+//!   return;
+//! }
+//! if (aMC.HasWarnings())                   // Check for the warnings
+//! {
+//!   // warnings treatment
+//!   Standard_SStream aSStream;
+//!   aMC.DumpWarnings(aSStream);
+//! }
+//!
+//! const TopoDS_Shape& aGluedShape = aMC.Shape(); // Connected shape
+//!
+//! // Checking material associations
+//! TopAbs_ShapeEnum anElemType = ...;       // Type of first BRep sub-element
+//! TopExp_Explorer anExp(anArguments.First(), anElemType);
+//! for (; anExp.More(); anExp.Next())
+//! {
+//!   const TopoDS_Shape& anElement = anExp.Current();
+//!   const TopTools_ListOfShape& aNegativeM = aMC.MaterialsOnNegativeSide(anElement);
+//!   const TopTools_ListOfShape& aPositiveM = aMC.MaterialsOnPositiveSide(anElement);
+//! }
+//!
+//! // Making the connected shape periodic
+//! BOPAlgo_MakePeriodic::PeriodicityParams aParams = ...; // Options for periodicity of the connected shape
+//! aMC.MakePeriodic(aParams);
+//!
+//! // Shape repetition after making it periodic
+//! // Check if the shape has been made periodic successfully
+//! if (aMC.PeriodicityTool().HasErrors())
+//! {
+//!   // Periodicity maker error treatment
+//! }
+//!
+//! // Shape repetition in periodic directions
+//! aMC.RepeatShape(0, 2);
+//!
+//! const TopoDS_Shape& aShape = aMC.PeriodicShape(); // Periodic and repeated shape
+//! ~~~~
+//!
+class BOPAlgo_MakeConnected : public BOPAlgo_Options
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+public: //! @name Constructor
+
+  //! Empty constructor
+  BOPAlgo_MakeConnected() : BOPAlgo_Options()
+  {
+  }
+
+
+public: //! @name Setters for the shapes to make connected
+
+  //! Sets the shape for making them connected.
+  //! @param theArgs [in] The arguments for the operation.
+  void SetArguments(const TopTools_ListOfShape& theArgs)
+  {
+    myArguments = theArgs;
+  }
+
+  //! Adds the shape to the arguments.
+  //! @param theS [in] One of the argument shapes.
+  void AddArgument(const TopoDS_Shape& theS)
+  {
+    myArguments.Append(theS);
+  }
+
+  //! Returns the list of arguments of the operation.
+  const TopTools_ListOfShape& Arguments() const
+  {
+    return myArguments;
+  }
+
+public: //! @name Performing the operations
+
+  //! Performs the operation, i.e. makes the input shapes connected.
+  Standard_EXPORT void Perform();
+
+
+public: //! @name Shape periodicity & repetition
+
+  //! Makes the connected shape periodic.
+  //! Repeated calls of this method overwrite the previous calls
+  //! working with the basis connected shape.
+  //! @param theParams [in] Periodic options.
+  Standard_EXPORT void MakePeriodic(const BOPAlgo_MakePeriodic::PeriodicityParams& theParams);
+
+  //! Performs repetition of the periodic shape in specified direction
+  //! required number of times.
+  //! @param theDirectionID [in] The direction's ID (0 for X, 1 for Y, 2 for Z);
+  //! @param theTimes [in] Requested number of repetitions (sign of the value defines
+  //!                      the side of the repetition direction (positive or negative)).
+  Standard_EXPORT void RepeatShape(const Standard_Integer theDirectionID,
+                                   const Standard_Integer theTimes);
+
+  //! Returns the periodicity tool.
+  const BOPAlgo_MakePeriodic& PeriodicityTool() const
+  {
+    return myPeriodicityMaker;
+  }
+
+
+public: //! @name Material transitions
+
+  //! Returns the original shapes which images contain the
+  //! the given shape with FORWARD orientation.
+  //! @param theS [in] The shape for which the materials are necessary.
+  const TopTools_ListOfShape& MaterialsOnPositiveSide(const TopoDS_Shape& theS)
+  {
+    const TopTools_ListOfShape* pLM = myMaterials.Seek(theS.Oriented(TopAbs_FORWARD));
+    return (pLM ? *pLM : EmptyList());
+  }
+
+  //! Returns the original shapes which images contain the
+  //! the given shape with REVERSED orientation.
+  //! @param theS [in] The shape for which the materials are necessary.
+  const TopTools_ListOfShape& MaterialsOnNegativeSide(const TopoDS_Shape& theS)
+  {
+    const TopTools_ListOfShape* pLM = myMaterials.Seek(theS.Oriented(TopAbs_REVERSED));
+    return (pLM ? *pLM : EmptyList());
+  }
+
+
+public: //! @name History methods
+
+  //! Returns the history of operations
+  const Handle(BRepTools_History)& History() const
+  {
+    return myHistory;
+  }
+
+  //! Returns the list of shapes modified from the given shape.
+  //! @param theS [in] The shape for which the modified shapes are necessary.
+  const TopTools_ListOfShape& GetModified(const TopoDS_Shape& theS)
+  {
+    return (myHistory.IsNull() ? EmptyList() : myHistory->Modified(theS));
+  }
+
+  //! Returns the list of original shapes from which the current shape has been created.
+  //! @param theS [in] The shape for which the origins are necessary.
+  const TopTools_ListOfShape& GetOrigins(const TopoDS_Shape& theS)
+  {
+    const TopTools_ListOfShape* pLOr = myOrigins.Seek(theS);
+    return (pLOr ? *pLOr : EmptyList());
+  }
+
+
+public: //! @name Getting the result shapes
+
+  //! Returns the resulting connected shape
+  const TopoDS_Shape& Shape() const
+  {
+    return myGlued;
+  }
+
+  //! Returns the resulting periodic & repeated shape
+  const TopoDS_Shape& PeriodicShape() const
+  {
+    return myShape;
+  }
+
+
+public: //! @name Clearing the contents of the algorithm from previous runs
+
+  //! Clears the contents of the algorithm.
+  void Clear()
+  {
+    BOPAlgo_Options::Clear();
+    myArguments.Clear();
+    myAllInputsMap.Clear();
+    myPeriodicityMaker.Clear();
+    myOrigins.Clear();
+    myMaterials.Clear();
+    if (!myGlueHistory.IsNull())
+      myGlueHistory->Clear();
+    if (!myHistory.IsNull())
+      myHistory->Clear();
+    myGlued.Nullify();
+    myShape.Nullify();
+  }
+
+
+protected: //! @name Protected methods performing the operation
+
+  //! Checks the validity of input data.
+  Standard_EXPORT void CheckData();
+
+  //! Makes the argument shapes connected (or glued).
+  Standard_EXPORT void MakeConnected();
+
+  //! Associates the materials transitions for the first BRep sub-elements:
+  //! - For input Solids, associates the Faces to Solids;
+  //! - For input Faces, associates the Edges to Faces;
+  //! - For input Edges, associates the Vertices to Edges.
+  Standard_EXPORT void AssociateMaterials();
+
+  //! Fills the map of origins
+  Standard_EXPORT void FillOrigins();
+
+private:
+
+  //! Returns an empty list.
+  const TopTools_ListOfShape& EmptyList()
+  {
+    static const TopTools_ListOfShape anEmptyList;
+    return anEmptyList;
+  }
+
+protected: //! @name Fields
+
+  // Inputs
+  TopTools_ListOfShape myArguments;          //!< Input shapes for making them connected
+  TopTools_IndexedMapOfShape myAllInputsMap; //!< Map of all BRep sub-elements of the input shapes
+
+  // Tools
+  BOPAlgo_MakePeriodic myPeriodicityMaker;   //!< Tool for making the shape periodic
+
+  // Results
+  NCollection_DataMap
+    <TopoDS_Shape,
+     TopTools_ListOfShape,
+     TopTools_OrientedShapeMapHasher> myMaterials; //!< Map of the materials associations
+                                                   //! for the first BRep sub-elements
+  TopTools_DataMapOfShapeListOfShape myOrigins;    //!< Map of origins
+                                                   //! (allows tracking the shape's ancestors)
+
+  Handle(BRepTools_History) myGlueHistory;         //!< Gluing History
+  Handle(BRepTools_History) myHistory;             //!< Final History of shapes modifications
+                                                   //! (including making the shape periodic and repetitions)
+
+  TopoDS_Shape myGlued;                            //!< The resulting connected (glued) shape
+  TopoDS_Shape myShape;                            //!< The resulting shape
+};
+
+#endif // _BOPAlgo_MakeConnected_HeaderFile
index b55d5fa22dced5753f3ab42a1aac6e4c32b030b4..93e305f96937762b3f2e9e5973832794bf2b9c22 100644 (file)
@@ -26,6 +26,8 @@ BOPAlgo_CheckResult.cxx
 BOPAlgo_CheckResult.hxx
 BOPAlgo_CheckStatus.hxx
 BOPAlgo_ListOfCheckResult.hxx
+BOPAlgo_MakeConnected.cxx
+BOPAlgo_MakeConnected.hxx
 BOPAlgo_MakePeriodic.cxx
 BOPAlgo_MakePeriodic.hxx
 BOPAlgo_MakerVolume.cxx
index 390497f0e39c4be3501a069af0628f65d039ad05..184b663f9f8a16679b9d0dc56f9f46539a34cb7d 100644 (file)
@@ -58,6 +58,7 @@ void  BOPTest::AllCommands(Draw_Interpretor& theCommands)
   BOPTest::UtilityCommands   (theCommands);
   BOPTest::RemoveFeaturesCommands(theCommands);
   BOPTest::PeriodicityCommands(theCommands);
+  BOPTest::MkConnectedCommands(theCommands);
 }
 //=======================================================================
 //function : Factory
index abf338dbe8987a38c0bea0d4945a8eeacc39164a..8a346592014c26b211b38b6f846d41d1576080c8 100644 (file)
@@ -62,6 +62,8 @@ public:
 
   Standard_EXPORT static void PeriodicityCommands (Draw_Interpretor& aDI);
 
+  Standard_EXPORT static void MkConnectedCommands (Draw_Interpretor& aDI);
+
   //! Prints errors and warnings if any and draws attached shapes 
   //! if flag BOPTest_Objects::DrawWarnShapes() is set
   Standard_EXPORT static void ReportAlerts (const Handle(Message_Report)& theReport);
diff --git a/src/BOPTest/BOPTest_MkConnectedCommands.cxx b/src/BOPTest/BOPTest_MkConnectedCommands.cxx
new file mode 100644 (file)
index 0000000..a00ce50
--- /dev/null
@@ -0,0 +1,342 @@
+// Created on: 04/02/2018
+// Created by: Eugeny MALTCHIKOV
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BOPTest.hxx>
+
+#include <BOPAlgo_MakeConnected.hxx>
+
+#include <BOPTest_DrawableShape.hxx>
+#include <BOPTest_Objects.hxx>
+
+#include <BRep_Builder.hxx>
+
+#include <BRepTest_Objects.hxx>
+
+#include <DBRep.hxx>
+#include <Draw.hxx>
+
+#include <Precision.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+
+static Standard_Integer MakeConnected(Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer MakePeriodic(Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer MaterialsOn(Draw_Interpretor&, Standard_Integer, const char**);
+static Standard_Integer RepeatShape(Draw_Interpretor&, Standard_Integer, const char**);
+
+namespace
+{
+  static BOPAlgo_MakeConnected TheMakeConnectedTool;
+}
+
+//=======================================================================
+//function : MkConnectedCommands
+//purpose  : 
+//=======================================================================
+void BOPTest::MkConnectedCommands(Draw_Interpretor& theCommands)
+{
+  static Standard_Boolean done = Standard_False;
+  if (done) return;
+  done = Standard_True;
+  // Chapter's name
+  const char* group = "BOPTest commands";
+  // Commands
+  theCommands.Add("makeconnected", "makeconnected result shape1 shape2 ...\n"
+                  "\t\tMake the given shapes connected (glued).",
+                  __FILE__, MakeConnected, group);
+
+  theCommands.Add("cmakeperiodic", "cmakeperiodic result [-x/y/z period [-trim first]]\n"
+                  "\t\tMake the connected shape periodic in the required directions.\n"
+                  "\t\tresult        - resulting periodic shape;\n"
+                  "\t\t-x/y/z period - option to make the shape periodic in X, Y or Z\n "
+                  "\t\t                direction with the given period;\n"
+                  "\t\t-trim first   - option to trim the shape to fit the required period,\n"
+                  "\t\t                starting the period in first.",
+                  __FILE__, MakePeriodic, group);
+
+  theCommands.Add("cmaterialson", "cmaterialson r +/- shape\n"
+                  "\t\tReturns the original shapes located on the required side of a shape:\n"
+                  "\t\t'+' - on a positive side of a shape (containing the shape with orientation FORWARD)\n"
+                  "\t\t'-' - on a negative side of a shape (containing the shape with orientation REVERSED).",
+                  __FILE__, MaterialsOn, group);
+
+  theCommands.Add("crepeatshape", "crepeatshape result -x/y/z times\n"
+                  "\t\tRepeats the periodic connected shape in periodic directions required number of times.\n"
+                  "\t\tresult       - resulting shape;\n"
+                  "\t\t-x/y/z times - direction for repetition and number of repetitions.",
+                  __FILE__, RepeatShape, group);
+}
+
+//=======================================================================
+//function : MakeConnected
+//purpose  : 
+//=======================================================================
+Standard_Integer MakeConnected(Draw_Interpretor& theDI,
+                               Standard_Integer  theArgc,
+                               const char ** theArgv)
+{
+  if (theArgc < 3)
+  {
+    theDI.PrintHelp(theArgv[0]);
+    return 1;
+  }
+
+  TheMakeConnectedTool.Clear();
+
+  for (Standard_Integer i = 2; i < theArgc; ++i)
+  {
+    TopoDS_Shape aS = DBRep::Get(theArgv[i]);
+    if (aS.IsNull())
+    {
+      theDI << "Error: " << theArgv[i] << " is a null shape. Skip it.\n";
+      continue;
+    }
+    TheMakeConnectedTool.AddArgument(aS);
+  }
+
+  TheMakeConnectedTool.SetRunParallel(BOPTest_Objects::RunParallel());
+
+  TheMakeConnectedTool.Perform();
+
+  // Print Error/Warning messages
+  BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
+
+  // Set the history of the operation in session
+  BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
+
+  if (TheMakeConnectedTool.HasErrors())
+    return 0;
+
+  // Draw the result shape
+  const TopoDS_Shape& aResult = TheMakeConnectedTool.Shape();
+  DBRep::Set(theArgv[1], aResult);
+
+  return 0;
+}
+
+//=======================================================================
+//function : MakePeriodic
+//purpose  : 
+//=======================================================================
+Standard_Integer MakePeriodic(Draw_Interpretor& theDI,
+                              Standard_Integer  theArgc,
+                              const char ** theArgv)
+{
+  if (theArgc < 4)
+  {
+    theDI.PrintHelp(theArgv[0]);
+    return 1;
+  }
+
+  if (TheMakeConnectedTool.Shape().IsNull() || TheMakeConnectedTool.HasErrors())
+  {
+    theDI << "Make the shapes connected first.\n";
+    return 1;
+  }
+
+  BOPAlgo_MakePeriodic::PeriodicityParams aParams;
+
+  for (Standard_Integer i = 2; i < theArgc;)
+  {
+    Standard_Integer aDirID = -1;
+    if (!strcasecmp(theArgv[i], "-x"))
+      aDirID = 0;
+    else if (!strcasecmp(theArgv[i], "-y"))
+      aDirID = 1;
+    else if (!strcasecmp(theArgv[i], "-z"))
+      aDirID = 2;
+    else
+    {
+      theDI << theArgv[i] << " - Invalid key\n";
+      return 1;
+    }
+
+    char cDirName[2];
+    sprintf(cDirName, "%c", theArgv[i][1]);
+
+    Standard_Real aPeriod = 0;
+    if (theArgc > i + 1)
+      aPeriod = Draw::Atof(theArgv[++i]);
+
+    if (aPeriod <= Precision::Confusion())
+    {
+      theDI << "Period for " << cDirName << " direction is not set\n";
+      return 1;
+    }
+
+    aParams.myPeriodic[aDirID] = Standard_True;
+    aParams.myPeriod[aDirID] = aPeriod;
+
+    ++i;
+    if (theArgc > i + 1)
+    {
+      // Check if trimming is necessary
+      if (!strcmp(theArgv[i], "-trim"))
+      {
+        if (theArgc == (i + 1))
+        {
+          theDI << "Trim bounds for " << cDirName << " direction are not set\n";
+          return 1;
+        }
+        Standard_Real aFirst = Draw::Atof(theArgv[++i]);
+
+        aParams.myIsTrimmed[aDirID] = Standard_False;
+        aParams.myPeriodFirst[aDirID] = aFirst;
+        ++i;
+      }
+    }
+  }
+
+  TheMakeConnectedTool.MakePeriodic(aParams);
+
+  // Print Error/Warning messages
+  BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
+
+  // Set the history of the operation in session
+  BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
+
+  if (TheMakeConnectedTool.HasErrors())
+    return 0;
+
+  // Draw the result shape
+  const TopoDS_Shape& aResult = TheMakeConnectedTool.PeriodicShape();
+  DBRep::Set(theArgv[1], aResult);
+
+  return 0;
+}
+
+//=======================================================================
+//function : RepeatShape
+//purpose  : 
+//=======================================================================
+Standard_Integer RepeatShape(Draw_Interpretor& theDI,
+                             Standard_Integer  theArgc,
+                             const char ** theArgv)
+{
+  if (theArgc < 4)
+  {
+    theDI.PrintHelp(theArgv[0]);
+    return 1;
+  }
+
+  if (TheMakeConnectedTool.PeriodicityTool().HasErrors())
+  {
+    theDI << "The shapes have not been made periodic yet.\n";
+    return 1;
+  }
+
+  for (Standard_Integer i = 2; i < theArgc; ++i)
+  {
+    Standard_Integer aDirID = -1;
+    if (!strcasecmp(theArgv[i], "-x"))
+      aDirID = 0;
+    else if (!strcasecmp(theArgv[i], "-y"))
+      aDirID = 1;
+    else if (!strcasecmp(theArgv[i], "-z"))
+      aDirID = 2;
+    else
+    {
+      theDI << theArgv[i] << " - Invalid key\n";
+      return 1;
+    }
+
+    char cDirName[2];
+    sprintf(cDirName, "%c", theArgv[i][1]);
+
+    Standard_Integer aTimes = 0;
+    if (theArgc > i + 1)
+      aTimes = Draw::Atoi(theArgv[++i]);
+
+    if (aTimes == 0)
+    {
+      theDI << "Number of repetitions for " << cDirName << " direction is not set\n";
+      return 1;
+    }
+
+    TheMakeConnectedTool.RepeatShape(aDirID, aTimes);
+  }
+
+  // Print Error/Warning messages
+  BOPTest::ReportAlerts(TheMakeConnectedTool.GetReport());
+
+  // Set the history of the operation in session
+  BRepTest_Objects::SetHistory(TheMakeConnectedTool.History());
+
+  if (TheMakeConnectedTool.HasErrors())
+    return 0;
+
+  // Draw the result shape
+  const TopoDS_Shape& aResult = TheMakeConnectedTool.PeriodicShape();
+  DBRep::Set(theArgv[1], aResult);
+
+  return 0;
+}
+
+//=======================================================================
+//function : MaterialsOn
+//purpose  : 
+//=======================================================================
+Standard_Integer MaterialsOn(Draw_Interpretor& theDI,
+                             Standard_Integer  theArgc,
+                             const char ** theArgv)
+{
+  if (theArgc != 4)
+  {
+    theDI.PrintHelp(theArgv[0]);
+    return 1;
+  }
+
+  // Get the shape to get materials
+  TopoDS_Shape aShape = DBRep::Get(theArgv[3]);
+  if (aShape.IsNull())
+  {
+    theDI << "Error: " << theArgv[3] << " is a null shape.\n";
+    return 1;
+  }
+
+  // Get the sign of a shape
+  Standard_Boolean bPositive;
+
+  if (!strcmp("+", theArgv[2]))
+    bPositive = Standard_True;
+  else if (!strcmp("-", theArgv[2]))
+    bPositive = Standard_False;
+  else
+  {
+    theDI << theArgv[2] << " - invalid key.\n";
+    return 1;
+  }
+
+  const TopTools_ListOfShape& aLS = bPositive ?
+    TheMakeConnectedTool.MaterialsOnPositiveSide(aShape) :
+    TheMakeConnectedTool.MaterialsOnNegativeSide(aShape);
+
+  TopoDS_Shape aResult;
+  if (aLS.IsEmpty())
+    theDI << "No materials on this side.\n";
+  else if (aLS.Extent() == 1)
+    aResult = aLS.First();
+  else
+  {
+    BRep_Builder().MakeCompound(TopoDS::Compound(aResult));
+    for (TopTools_ListIteratorOfListOfShape it(aLS); it.More(); it.Next())
+      BRep_Builder().Add(aResult, it.Value());
+  }
+
+  DBRep::Set(theArgv[1], aResult);
+
+  return 0;
+}
index a2ceac1a982c6f4259b00d4fe0c81fe2c05521e4..dfac503cc5f89fe240d7315bced6932bb62d0c11 100755 (executable)
@@ -6,6 +6,7 @@ BOPTest_CheckCommands.cxx
 BOPTest_DrawableShape.cxx
 BOPTest_DrawableShape.hxx
 BOPTest_LowCommands.cxx
+BOPTest_MkConnectedCommands.cxx
 BOPTest_ObjCommands.cxx
 BOPTest_Objects.cxx
 BOPTest_Objects.hxx
index cd196015d543aa745f8b3c69e6080632cc26e7e2..e1564633a4cde809caee68d347d4a40d0ac96a9b 100644 (file)
@@ -29,4 +29,5 @@
 029 splitter
 030 history
 031 removefeatures
-032 periodicity
\ No newline at end of file
+032 periodicity
+033 mkconnected
diff --git a/tests/boolean/mkconnected/A1 b/tests/boolean/mkconnected/A1
new file mode 100644 (file)
index 0000000..c6703f4
--- /dev/null
@@ -0,0 +1,61 @@
+polyline p 0 0 0 10 0 0 10 0 10 5 0 10 5 0 5 0 0 5 0 0 0
+mkplane f p
+prism b1 f 0 5 0
+box b2 0 0 5 5 5 5
+box b3 0 5 0 10 5 10
+
+# make the shapes connected
+makeconnected c b3 b1 b2
+
+checkshape c
+checknbshapes c -vertex 18 -edge 31 -wire 17 -face 17 -shell 3 -solid 3
+checkprops c -s 900 -v 1000
+
+savehistory h
+
+modified m3 h b3
+checknbshapes m3 -face 7
+
+# make the shape periodic
+cmakeperiodic cp -x 10 -y 10 -z 10
+checknbshapes cp -vertex 26 -edge 42 -wire 20 -face 20 -shell 3 -solid 3
+
+savehistory h
+
+modified m1 h b1
+checknbshapes m1 -face 10
+
+modified m2 h b2
+checknbshapes m2 -ref [nbshapes b2]
+
+modified m3 h b3
+checknbshapes m3 -face 8
+
+
+# check material associations
+explode b3 f
+
+# the face b3_3 is REVERSED
+# materials on negative side should be only b3
+# materials on positive side should be b1 and b2
+
+modified mf h b3_3
+
+compound pos 
+compound neg
+
+foreach f [explode mf f] {
+  if {![regexp "No materials on this side" [cmaterialson p + $f]]} {
+    add p pos
+  }
+  if {![regexp "No materials on this side" [cmaterialson n - $f]]} {
+    add n neg
+  }
+}
+
+# check that neg contains b3 only
+checkprops neg -equal b3 -skip
+
+# check that pos contains both 
+compound b1 b2 comp
+checkprops pos -equal comp -skip
diff --git a/tests/boolean/mkconnected/A2 b/tests/boolean/mkconnected/A2
new file mode 100644 (file)
index 0000000..5d77b0e
--- /dev/null
@@ -0,0 +1,90 @@
+box b1 10 10 5
+box b2 0 0 5 10 10 1
+box b3 0 0 6 3 3 4
+polyline p 3 0 6 3 3 6 0 3 6 0 4 6 4 4 6 4 0 6 3 0 6
+mkplane f p
+prism b4 f  0 0 4
+box b5 0 9 6 4 1 4
+box b6 9 9 6 1 1 4
+box b7 9 0 6 1 3 4
+
+# make the solids connected
+makeconnected c b1 b2 b3 b4 b5 b6 b7
+
+checkshape c
+checknbshapes c -vertex 46 -edge 79 -wire 41 -face 41 -shell 7 -solid 7
+checkprops c -s 888 -v 696
+
+savehistory h
+
+explode b6 f
+modified f h b6_4
+
+cmaterialson pos + f
+if {![regexp "equal shapes" [compare pos b6]]} {
+  puts "Error: incorrect material associations"
+}
+
+if {![regexp "No materials on this side." [cmaterialson neg - f]]} {
+  puts "Error: incorrect material associations"
+}
+
+# make the connected shape periodic
+cmakeperiodic cp -x 10 -y 10
+checkshape cp
+checknbshapes cp -vertex 49 -edge 83 -wire 42 -face 42 -shell 7 -solid 7
+checkprops cp -s 888 -v 696
+
+# get modifications of the fifth solid
+savehistory h
+
+modified m5 h b5
+checknbshapes m5 -vertex 10 -edge 15 -wire 7 -face 7 -shell 1 -solid 1
+checkprops m5 -s 48 -v 16
+
+
+# repeat shape
+crepeatshape res1 -x -1 -y -1 -x 1 -y 1
+
+checknbshapes res1 -vertex 496 -edge 947 -wire 564 -face 564 -shell 112 -solid 112
+checkprops res1 -s 14208 -v 11136
+
+
+savehistory h
+modified f h b6_4
+
+cmaterialson pos + f
+cmaterialson neg - f
+
+if {![regexp "equal shapes" [compare pos b6]]} {
+  puts "Error: incorrect material associations"
+}
+
+if {![regexp "equal shapes" [compare neg b7]]} {
+  puts "Error: incorrect material associations"
+}
+
+
+# make the connected shape periodic with period grater than the unit cell
+cmakeperiodic cp -x 12 -trim -1 -y 12 -trim -1
+
+checknbshapes cp -ref [nbshapes c]
+checkprops cp -equal c
+
+crepeatshape res2 -x -1 -y -1 -x 1 -y 1
+
+checknbshapes res2 -vertex 736 -edge 1264 -wire 656 -face 656 -shell 112 -solid 112
+checkprops res2 -s 14208 -v 11136
+
+savehistory h
+
+modified f h b6_4
+
+cmaterialson pos + f
+if {![regexp "equal shapes" [compare pos b6]]} {
+  puts "Error: incorrect material associations"
+}
+
+if {![regexp "No materials on this side." [cmaterialson neg - f]]} {
+  puts "Error: incorrect material associations"
+}