0024019: Voxel_FastConverter: filling problem
authorPawel <pawel-kowalski@wp.pl>
Thu, 4 Jul 2013 10:29:08 +0000 (14:29 +0400)
committerPawel <pawel-kowalski@wp.pl>
Thu, 4 Jul 2013 10:29:08 +0000 (14:29 +0400)
Added a new method filling the inner part of a shape with voxels. The advantages of using this method are:
- processing vertical faces
- correct processing of 'concave' shapes
Added QA command OCC24019 for issue 24019 and test case bugs/vis/bug24019

src/QABugs/QABugs_19.cxx
src/TKQADraw/EXTERNLIB
src/Voxel/Voxel_FastConverter.cdl
src/Voxel/Voxel_FastConverter.cxx
tests/bugs/vis/bug24019 [new file with mode: 0644]

index 99842aa..f50e608 100755 (executable)
@@ -630,6 +630,53 @@ static Standard_Integer OCC23945 (Draw_Interpretor& di,Standard_Integer n, const
   return 0;
 }
 
+#include <Voxel_BoolDS.hxx>
+#include <Voxel_FastConverter.hxx>
+#include <Voxel_BooleanOperation.hxx>
+static Standard_Integer OCC24019 (Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
+{
+  if ( argc != 2 ) {
+    di << "Error: " << argv[0] << " - invalid number of arguments" << "\n";
+       return 1;
+  }
+
+  TCollection_AsciiString aFileName = argv[1];
+  TopoDS_Shape aShape;
+  BRep_Builder aBuilder;
+
+  if (!BRepTools::Read(aShape, aFileName.ToCString(), aBuilder)) {
+    di << "Error: Could not read a shape!" << "\n";
+       return 1;
+  }
+  
+  TopoDS_Solid aShape1 = BRepPrimAPI_MakeSphere(gp_Pnt(20,25,35), 7);
+
+  Standard_Real deflection = 0.005;
+  Standard_Integer nbThreads = 1;
+  Standard_Integer nbx = 200, nby = 200, nbz = 200;
+  Voxel_BoolDS theVoxels(0,0,0, 50, 50, 50, nbx, nby, nbz);
+  Voxel_BoolDS theVoxels1(0,0,0, 50, 50, 50, nbx, nby, nbz);
+
+  Standard_Integer progress = 0;
+  Voxel_FastConverter fcp(aShape, theVoxels, deflection, nbx, nby, nbz, nbThreads);
+  fcp.ConvertUsingSAT(progress, 1);
+  fcp.FillInVolume(1);
+
+  Voxel_FastConverter fcp1(aShape1, theVoxels1, deflection, nbx, nby, nbz, nbThreads);
+  fcp1.ConvertUsingSAT(progress, 1);
+  fcp1.FillInVolume(1);
+
+  Voxel_BooleanOperation op;
+  Standard_Boolean result = op.Cut(theVoxels1, theVoxels);
+  if ( result != 1 ) {
+    di << "Error: invalid boolean operation" << "\n";
+  } else {
+       di << "OK: boolean operation is ok" << "\n";
+  }
+
+  return 0;
+}
+
 void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -647,6 +694,8 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
   theCommands.Add ("OCC23952intersect", "OCC23952intersect nbsol shape1 shape2", __FILE__, OCC23952intersect, group);
   theCommands.Add ("test_offset", "test_offset", __FILE__, test_offset, group);
   theCommands.Add("OCC23945", "OCC23945 surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]", __FILE__, OCC23945,group);
+  theCommands.Add ("OCC24019", "OCC24019 aShape", __FILE__, OCC24019, group);
+
   return;
 }
 
index 56f81e0..65ff872 100755 (executable)
@@ -33,6 +33,7 @@ TKXDESTEP
 TKXSDRAW
 TKSTL
 TKAdvTools
+TKVoxel
 CSF_TclLibs
 CSF_TclTkLibs
 CSF_gdi32
index ae95d59..37898c5 100755 (executable)
@@ -100,6 +100,17 @@ is
                 ithread : Integer from Standard = 1)
     ---Purpose: Fills-in volume of the shape by a value.
     returns Boolean from Standard;
+    
+    FillInVolume(me : in out;
+                 inner : Byte from Standard;
+                 shape : Shape   from TopoDS;
+                 ithread : Integer from Standard = 1)
+    ---Purpose: Fills-in volume of the shape by a value.
+    --          Uses the topological information from the provided shape
+    --          to judge whether points are inside the shape or not
+    --          (only when processing vertical faces).
+    --          The inner value has to be positive.
+    returns Boolean from Standard;
 
 
     ---Category: Private area
index 1401044..32c9eba 100755 (executable)
@@ -35,6 +35,7 @@
 #include <ElSLib.hxx>
 #include <Poly_Triangulation.hxx>
 #include <IntAna2d_AnaIntersection.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 
 // Printing the progress in stdout.
 //#define CONV_DUMP
@@ -531,6 +532,103 @@ Standard_Boolean Voxel_FastConverter::FillInVolume(const Standard_Byte inner,
   return Standard_True;
 }
 
+Standard_Boolean Voxel_FastConverter::FillInVolume(const Standard_Byte inner, const TopoDS_Shape & shape, const Standard_Integer ithread)
+{
+  Voxel_DS* ds = (Voxel_DS*) myVoxels;
+  Standard_Integer ix, iy, iz, nbx = ds->GetNbX(), nby = ds->GetNbY(), nbz = ds->GetNbZ();
+  Standard_Boolean prev_surface, surface, volume, isOnVerticalSurface;
+
+  BRepClass3d_SolidClassifier solidClassifier(shape);
+  Standard_Real xc, yc, zc;
+
+  if (inner)
+  {
+    // Fill-in internal voxels by the value "inner"
+    for (ix = 0; ix < nbx; ix++)
+    {
+      for (iy = 0; iy < nby; iy++)
+      {
+        // Check existence of volume.
+        volume = Standard_False;
+        surface = Standard_False;
+        prev_surface = Standard_False;
+        isOnVerticalSurface = Standard_False;
+        for (iz = 0; iz < nbz; iz++)
+        {
+          surface = (myIsBool == 1) ? 
+            ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz) == Standard_True : 
+              ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz) > 0;
+          if (prev_surface && !surface)
+          {
+            if(isOnVerticalSurface)
+            {
+              isOnVerticalSurface = Standard_False;
+              ((Voxel_BoolDS*)myVoxels)->GetCenter(ix, iy, iz, xc, yc, zc);
+              gp_Pnt P(xc, yc, zc);
+              solidClassifier.Perform(P, Precision::Confusion());
+
+              if(solidClassifier.State() == TopAbs_IN)
+                volume = Standard_True;
+              else
+                volume = Standard_False;
+            }
+            else
+              volume = !volume;
+          }
+          if(prev_surface && surface)
+            isOnVerticalSurface = Standard_True;
+          else
+            isOnVerticalSurface = Standard_False;
+          prev_surface = surface;
+        }
+        if (volume)
+          continue;
+
+        // Fill-in the volume.
+        volume = Standard_False;
+        surface = Standard_False;
+        prev_surface = Standard_False;
+        isOnVerticalSurface = Standard_False;
+        for (iz = 0; iz < nbz; iz++)
+        {
+          surface = (myIsBool == 1) ? 
+            ((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz) == Standard_True : 
+              ((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz) > 0;
+          if (prev_surface && !surface)
+          {
+            if(isOnVerticalSurface)
+            {
+              isOnVerticalSurface = Standard_False;
+              ((Voxel_BoolDS*)myVoxels)->GetCenter(ix, iy, iz, xc, yc, zc);
+              gp_Pnt P(xc, yc, zc);
+              solidClassifier.Perform(P, Precision::Confusion());
+
+              if(solidClassifier.State() == TopAbs_IN)
+                volume = Standard_True;
+              else
+                volume = Standard_False;
+            }
+            else
+              volume = !volume;
+          }
+          if (volume && !surface)
+          {
+            (myIsBool == 1) ? ((Voxel_BoolDS*)myVoxels)->Set(ix, iy, iz, inner) : 
+              ((Voxel_ColorDS*)myVoxels)->Set(ix, iy, iz, inner);
+          }
+          if(prev_surface && surface)
+            isOnVerticalSurface = Standard_True;
+          else
+            isOnVerticalSurface = Standard_False;
+          prev_surface = surface;
+        }
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
 void Voxel_FastConverter::GetBndBox(const gp_Pnt&  p1,
                                    const gp_Pnt&  p2,
                                    const gp_Pnt&  p3,
diff --git a/tests/bugs/vis/bug24019 b/tests/bugs/vis/bug24019
new file mode 100644 (file)
index 0000000..d70ed56
--- /dev/null
@@ -0,0 +1,9 @@
+puts "==========="
+puts "OCC24019"
+puts "==========="
+
+##########################################
+# Voxel_FastConverter: filleng problem
+##########################################
+
+OCC24019 [locate_data_file bug24019_boxes5.brep]