mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
2
src/Voxel/FILES
Executable file
2
src/Voxel/FILES
Executable file
@@ -0,0 +1,2 @@
|
||||
Voxel_VisData.h
|
||||
Voxel_TypeDef.hxx
|
96
src/Voxel/Voxel.cdl
Executable file
96
src/Voxel/Voxel.cdl
Executable file
@@ -0,0 +1,96 @@
|
||||
-- File: Voxel.cdl
|
||||
-- Created: Sun May 04 09:39:16 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
package Voxel
|
||||
|
||||
---Purpose: Data structuire and visualization engine for voxel modeling.
|
||||
|
||||
uses
|
||||
|
||||
IntCurvesFace,
|
||||
TCollection,
|
||||
SelectMgr,
|
||||
Quantity,
|
||||
TopTools,
|
||||
TColStd,
|
||||
TColgp,
|
||||
TopoDS,
|
||||
PrsMgr,
|
||||
Prs3d,
|
||||
Poly,
|
||||
V3d,
|
||||
AIS,
|
||||
Bnd,
|
||||
gp
|
||||
|
||||
is
|
||||
|
||||
enumeration VoxelDisplayMode is
|
||||
VDM_POINTS,
|
||||
VDM_NEARESTPOINTS,
|
||||
VDM_BOXES,
|
||||
VDM_NEARESTBOXES
|
||||
end VoxelDisplayMode;
|
||||
|
||||
enumeration VoxelFileFormat is
|
||||
VFF_ASCII,
|
||||
VFF_BINARY
|
||||
end VoxelFileFormat;
|
||||
|
||||
-- A base class for all voxels data structures.
|
||||
class DS;
|
||||
|
||||
-- A voxel model keeping a boolean flag for each voxel (1 || 0).
|
||||
class BoolDS;
|
||||
|
||||
-- A voxel model keeping a boolean flag for each voxel
|
||||
-- with an opportunity to split a voxel into 8 sub-voxels.
|
||||
class OctBoolDS;
|
||||
|
||||
-- A voxel model keeping a boolean flag for each voxel
|
||||
-- with an opportunity to split a voxel into 8 sub-voxels
|
||||
-- recursively.
|
||||
class ROctBoolDS;
|
||||
private class SplitData;
|
||||
|
||||
-- A voxel model keeping 4 bits of information for each voxel (16 colors).
|
||||
class ColorDS;
|
||||
|
||||
-- A voxel model keeping 4 bytes of information for each voxel (a floating-point value).
|
||||
class FloatDS;
|
||||
|
||||
|
||||
-- A converter of a shape to voxel model.
|
||||
--class Converter;
|
||||
|
||||
-- An internal class searching intersections between a line and a shape.
|
||||
--class ShapeIntersector;
|
||||
|
||||
-- An alternative method of conversion of a shape into voxels.
|
||||
-- It is faster, but less precise.
|
||||
class FastConverter;
|
||||
|
||||
--- Converts voxels into triangulation
|
||||
--class Triangulator;
|
||||
|
||||
-- Interactive object of voxels
|
||||
class Prs;
|
||||
|
||||
-- Boolean operations for voxels.
|
||||
class BooleanOperation;
|
||||
|
||||
-- Collision detection
|
||||
class CollisionDetection;
|
||||
|
||||
-- Selection of voxels in the viewer 3d
|
||||
class Selector;
|
||||
|
||||
-- Ascii writer/reader of voxels
|
||||
class Writer;
|
||||
class Reader;
|
||||
|
||||
|
||||
end Voxel;
|
74
src/Voxel/Voxel_BoolDS.cdl
Executable file
74
src/Voxel/Voxel_BoolDS.cdl
Executable file
@@ -0,0 +1,74 @@
|
||||
-- File: Voxel_BoolDS.cdl
|
||||
-- Created: Sun May 04 09:50:26 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class BoolDS from Voxel inherits DS from Voxel
|
||||
|
||||
---Purpose: A 3D voxel model keeping a bool flag (1 or 0)
|
||||
-- value for each voxel.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns BoolDS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns BoolDS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is redefined virtual;
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of the voxel model.
|
||||
|
||||
SetZero(me : in out);
|
||||
---Purpose: The method sets all values equal to 0 (false) and
|
||||
-- releases the memory.
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
data : Boolean from Standard = Standard_True);
|
||||
---Purpose: Defines a value for voxel with co-ordinates (ix, iy, iz).
|
||||
-- Initial state of the model is so that all voxels have value 0 (false),
|
||||
-- and this data doesn't occupy memory.
|
||||
-- Memory for data is allocating during setting non-zero values (true).
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the value of voxel with co-ordinates (ix, iy, iz).
|
||||
returns Boolean from Standard;
|
||||
|
||||
end BoolDS;
|
131
src/Voxel/Voxel_BoolDS.cxx
Executable file
131
src/Voxel/Voxel_BoolDS.cxx
Executable file
@@ -0,0 +1,131 @@
|
||||
// File: Voxel_BoolDS.cxx
|
||||
// Created: Mon Jun 21 14:35:37 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_BoolDS.ixx>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static Standard_Byte gbits[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
||||
static Standard_Byte gnbits[8] = {255-1, 255-2, 255-4, 255-8, 255-16, 255-32, 255-64, 255-128};
|
||||
|
||||
// Empty constructor
|
||||
Voxel_BoolDS::Voxel_BoolDS():Voxel_DS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_BoolDS::Voxel_BoolDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
:Voxel_DS()
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_BoolDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
if (!myNbX || !myNbY || !myNbZ)
|
||||
return;
|
||||
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
myData = (Standard_Address) calloc(nb_slices, sizeof(Standard_Byte*));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_BoolDS::Destroy()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
SetZero();
|
||||
free((Standard_Byte**)myData);
|
||||
myData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_BoolDS::SetZero()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
Standard_Integer ix = 0, nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
for (; ix < nb_slices; ix++)
|
||||
{
|
||||
if (((Standard_Byte**)myData)[ix])
|
||||
{
|
||||
free(((Standard_Byte**)myData)[ix]);
|
||||
((Standard_Byte**)myData)[ix] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Access to the boolean information attached to a particular voxel:
|
||||
// Info: (ix >= 0 && ix < theNb_x), etc.
|
||||
void Voxel_BoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Boolean data)
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 6;
|
||||
|
||||
if (!data && !((Standard_Byte**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
{
|
||||
((Standard_Byte**)myData)[islice] = (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
|
||||
// Index within 8 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 6);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[shift]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[shift];
|
||||
else
|
||||
value &= gnbits[shift];
|
||||
((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte] = value;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 6;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// Index within 8 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 6);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
return ((value & gbits[shift]) ? Standard_True : Standard_False);
|
||||
}
|
102
src/Voxel/Voxel_BooleanOperation.cdl
Executable file
102
src/Voxel/Voxel_BooleanOperation.cdl
Executable file
@@ -0,0 +1,102 @@
|
||||
-- File: Voxel_BooleanOperation.cdl
|
||||
-- Created: Wed May 21 10:59:19 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class BooleanOperation from Voxel
|
||||
|
||||
---Purpose: Boolean operations (fuse, cut)
|
||||
-- for voxels of the same dimension.
|
||||
|
||||
uses
|
||||
|
||||
DS from Voxel,
|
||||
BoolDS from Voxel,
|
||||
ColorDS from Voxel,
|
||||
FloatDS from Voxel
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns BooleanOperation from Voxel;
|
||||
|
||||
|
||||
---Category: Fusion
|
||||
-- ======
|
||||
|
||||
Fuse(me;
|
||||
theVoxels1 : in out BoolDS from Voxel;
|
||||
theVoxels2 : in BoolDS from Voxel)
|
||||
---Purpose: Fuses two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Fuse(me;
|
||||
theVoxels1 : in out ColorDS from Voxel;
|
||||
theVoxels2 : in ColorDS from Voxel)
|
||||
---Purpose: Fuses two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
-- It summerizes the value of corresponding voxels and puts the result to theVoxels1.
|
||||
-- If the result exceeds 15 or becomes greater, it keeps 15.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Fuse(me;
|
||||
theVoxels1 : in out FloatDS from Voxel;
|
||||
theVoxels2 : in FloatDS from Voxel)
|
||||
---Purpose: Fuses two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
-- It summerizes the value of corresponding voxels and puts the result to theVoxels1.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Cut
|
||||
-- ===
|
||||
|
||||
Cut(me;
|
||||
theVoxels1 : in out BoolDS from Voxel;
|
||||
theVoxels2 : in BoolDS from Voxel)
|
||||
---Purpose: Cuts two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Cut(me;
|
||||
theVoxels1 : in out ColorDS from Voxel;
|
||||
theVoxels2 : in ColorDS from Voxel)
|
||||
---Purpose: Cuts two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
-- It subtracts the value of corresponding voxels and puts the result to theVoxels1.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Cut(me;
|
||||
theVoxels1 : in out FloatDS from Voxel;
|
||||
theVoxels2 : in FloatDS from Voxel)
|
||||
---Purpose: Cuts two cubes of voxels.
|
||||
-- It modifies the first cube of voxels.
|
||||
-- It returns false in case of different dimension of the cube,
|
||||
-- different number of voxels.
|
||||
-- It subtracts the value of corresponding voxels and puts the result to theVoxels1.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Private area
|
||||
-- ============
|
||||
|
||||
Check(me;
|
||||
theVoxels1 : DS from Voxel;
|
||||
theVoxels2 : DS from Voxel)
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
end BooleanOperation;
|
215
src/Voxel/Voxel_BooleanOperation.cxx
Executable file
215
src/Voxel/Voxel_BooleanOperation.cxx
Executable file
@@ -0,0 +1,215 @@
|
||||
// File: Voxel_BooleanOperation.cxx
|
||||
// Created: Mon May 21 12:34:54 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_BooleanOperation.ixx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
Voxel_BooleanOperation::Voxel_BooleanOperation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Fuse( Voxel_BoolDS& theVoxels1,
|
||||
const Voxel_BoolDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Take the values of the second cube and put them to the first one.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_Boolean value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
theVoxels1.Set(ix, iy, iz, value2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Fuse( Voxel_ColorDS& theVoxels1,
|
||||
const Voxel_ColorDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Take the values of the second cube and put them to the first one.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_Byte value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
{
|
||||
Standard_Byte value1 = theVoxels1.Get(ix, iy, iz);
|
||||
Standard_Byte value = value1 + value2;
|
||||
if (value > 15)
|
||||
value = 15;
|
||||
theVoxels1.Set(ix, iy, iz, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Fuse( Voxel_FloatDS& theVoxels1,
|
||||
const Voxel_FloatDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Take the values of the second cube and put them to the first one.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_ShortReal value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
{
|
||||
Standard_ShortReal value1 = theVoxels1.Get(ix, iy, iz);
|
||||
theVoxels1.Set(ix, iy, iz, value1 + value2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Cut( Voxel_BoolDS& theVoxels1,
|
||||
const Voxel_BoolDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Subtract the values.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_Boolean value1 = theVoxels1.Get(ix, iy, iz);
|
||||
if (value1)
|
||||
{
|
||||
Standard_Boolean value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
theVoxels1.Set(ix, iy, iz, Standard_False);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Cut( Voxel_ColorDS& theVoxels1,
|
||||
const Voxel_ColorDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Subtract the values.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_Byte value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
{
|
||||
Standard_Byte value1 = theVoxels1.Get(ix, iy, iz);
|
||||
if (value1)
|
||||
{
|
||||
Standard_Integer value = value1 - value2;
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
theVoxels1.Set(ix, iy, iz, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Cut( Voxel_FloatDS& theVoxels1,
|
||||
const Voxel_FloatDS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
if (!Check(theVoxels1, theVoxels2))
|
||||
return Standard_False;
|
||||
|
||||
// Subtract the values.
|
||||
Standard_Integer ix, iy, iz;
|
||||
for (iz = 0; iz < theVoxels2.GetNbZ(); iz++)
|
||||
{
|
||||
for (iy = 0; iy < theVoxels2.GetNbY(); iy++)
|
||||
{
|
||||
for (ix = 0; ix < theVoxels2.GetNbX(); ix++)
|
||||
{
|
||||
Standard_ShortReal value2 = theVoxels2.Get(ix, iy, iz);
|
||||
if (value2)
|
||||
{
|
||||
Standard_ShortReal value1 = theVoxels1.Get(ix, iy, iz);
|
||||
theVoxels1.Set(ix, iy, iz, value1 - value2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_BooleanOperation::Check(const Voxel_DS& theVoxels1,
|
||||
const Voxel_DS& theVoxels2) const
|
||||
{
|
||||
// Check the voxels
|
||||
// Number of splits along X, Y and Z axes.
|
||||
if (!theVoxels1.GetNbX() && theVoxels1.GetNbX() != theVoxels2.GetNbX())
|
||||
return Standard_False;
|
||||
if (!theVoxels1.GetNbY() && theVoxels1.GetNbY() != theVoxels2.GetNbY())
|
||||
return Standard_False;
|
||||
if (!theVoxels1.GetNbZ() && theVoxels1.GetNbZ() != theVoxels2.GetNbZ())
|
||||
return Standard_False;
|
||||
// Start point
|
||||
if (fabs(theVoxels1.GetX() - theVoxels2.GetX()) > Precision::Confusion() ||
|
||||
fabs(theVoxels1.GetY() - theVoxels2.GetY()) > Precision::Confusion() ||
|
||||
fabs(theVoxels1.GetZ() - theVoxels2.GetZ()) > Precision::Confusion())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
// Length along X, Y and Z axes.
|
||||
if (fabs(theVoxels1.GetXLen() - theVoxels2.GetXLen()) > Precision::Confusion() ||
|
||||
fabs(theVoxels1.GetYLen() - theVoxels2.GetYLen()) > Precision::Confusion() ||
|
||||
fabs(theVoxels1.GetZLen() - theVoxels2.GetZLen()) > Precision::Confusion())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
162
src/Voxel/Voxel_CollisionDetection.cdl
Executable file
162
src/Voxel/Voxel_CollisionDetection.cdl
Executable file
@@ -0,0 +1,162 @@
|
||||
-- File: Voxel_CollisionDetection.cdl
|
||||
-- Created: Mon Jul 14 13:18:04 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class CollisionDetection from Voxel
|
||||
|
||||
---Purpose: Detects collisions between shapes.
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
ListOfShape from TopTools,
|
||||
BoolDS from Voxel,
|
||||
Box from Bnd
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns CollisionDetection from Voxel;
|
||||
|
||||
|
||||
---Category: Initialization
|
||||
-- ==============
|
||||
|
||||
Create(deflection : Real from Standard;
|
||||
nbx : Integer from Standard;
|
||||
nby : Integer from Standard;
|
||||
nbz : Integer from Standard)
|
||||
---Purpose: A constructor.
|
||||
-- It defines deflection of triangulation for the shapes.
|
||||
-- As lower the deflection is, as proper the triangulation is generated.
|
||||
-- Also, it defines number of splits along X, Y and Z axes for generation of voxels.
|
||||
-- As greater the numbers are, as greater number of voxels is used for detection of collision.
|
||||
returns CollisionDetection from Voxel;
|
||||
|
||||
AddShape(me : in out;
|
||||
shape : Shape from TopoDS)
|
||||
---Purpose: Adds a shape.
|
||||
-- Returns an index of the shape.
|
||||
returns Integer from Standard;
|
||||
|
||||
ReplaceShape(me : in out;
|
||||
ishape : Integer from Standard;
|
||||
shape : Shape from TopoDS)
|
||||
---Purpose: Replaces a shape by another one.
|
||||
-- <ishape> is an index of the shape.
|
||||
-- This method is useful for moving shape, for example.
|
||||
returns Boolean from Standard;
|
||||
|
||||
SetDeflection(me : in out;
|
||||
deflection : Real from Standard);
|
||||
---Purpose: Defines the deflection of triangulation of shapes.
|
||||
|
||||
SetNbVoxels(me : in out;
|
||||
nbx : Integer from Standard;
|
||||
nby : Integer from Standard;
|
||||
nbz : Integer from Standard);
|
||||
---Purpose: Defines the number of voxels along X, Y and Z axes.
|
||||
|
||||
SetBoundaryBox(me : in out;
|
||||
box: Box from Bnd);
|
||||
---Purpose: Defines a user-defined boundary box for generation of voxels.
|
||||
-- If this method is not called, the algorithm calculates the boundary box itself.
|
||||
|
||||
SetUsageOfVolume(me : in out;
|
||||
usage : Boolean from Standard);
|
||||
---Purpose: Defines usage of volume of shapes in collision detection algorithm.
|
||||
-- Beware, usage of volume a little bit decreases the speed of algorithm.
|
||||
|
||||
KeepCollisions(me : in out;
|
||||
keep : Boolean from Standard);
|
||||
---Purpose: Doesn't clean the collision points on new call to the method Compute().
|
||||
-- It allows to see the collisions for a moving shape.
|
||||
|
||||
|
||||
---Category: Computation
|
||||
-- ===========
|
||||
|
||||
-- Call the method in the following order:
|
||||
-- Voxelize();
|
||||
-- Compute();
|
||||
|
||||
Voxelize(me : in out;
|
||||
ishape : Integer from Standard = -1)
|
||||
---Purpose: Prepares data for computation of collisions.
|
||||
-- It checks the inner parameters (number of voxels along X, Y and Z axes) and
|
||||
-- voxelizes the shapes.
|
||||
-- If the shape is not changed since the last call to this method,
|
||||
-- this method may be not called for this shape.
|
||||
-- <ishape> - is the index of the shape for processing by this method.
|
||||
-- If it is equal to -1, all shapes will be processed.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Compute(me : in out)
|
||||
---Purpose: Computes the collisions.
|
||||
-- This method may be called many times if, for example, the shapes are being moved.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Result (collisions)
|
||||
-- ===================
|
||||
|
||||
HasCollisions(me)
|
||||
---Purpose: Returns true if a collision is detected.
|
||||
returns Boolean from Standard;
|
||||
|
||||
GetCollisions(me)
|
||||
---C++: return const &
|
||||
---Purpose: Returns the collided voxels.
|
||||
returns BoolDS from Voxel;
|
||||
|
||||
|
||||
---Category: Some internal methods
|
||||
-- =====================
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor.
|
||||
|
||||
Clear(me : in out)
|
||||
---Purpose: An internal method for cleaning the intermediate data.
|
||||
is private;
|
||||
|
||||
CheckVoxels(me;
|
||||
voxels : BoolDS from Voxel)
|
||||
---Purpose: An internal method, which checks correspondance
|
||||
-- of voxels to the parameters defined by user.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
-- Initial data.
|
||||
myShapes : ListOfShape from TopTools;
|
||||
myDeflection : Real from Standard;
|
||||
myNbX : Integer from Standard;
|
||||
myNbY : Integer from Standard;
|
||||
myNbZ : Integer from Standard;
|
||||
myUsageOfVolume : Boolean from Standard;
|
||||
myKeepCollisions : Boolean from Standard;
|
||||
|
||||
-- User-defined boundary box of shapes.
|
||||
myX : Real from Standard;
|
||||
myY : Real from Standard;
|
||||
myZ : Real from Standard;
|
||||
myXLen : Real from Standard;
|
||||
myYLen : Real from Standard;
|
||||
myZLen : Real from Standard;
|
||||
|
||||
-- An array of voxels of all shapes.
|
||||
myVoxels : Address from Standard;
|
||||
|
||||
-- The result.
|
||||
myCollisions : BoolDS from Voxel;
|
||||
myHasCollisions : Boolean from Standard;
|
||||
|
||||
|
||||
end CollisionDetection;
|
284
src/Voxel/Voxel_CollisionDetection.cxx
Executable file
284
src/Voxel/Voxel_CollisionDetection.cxx
Executable file
@@ -0,0 +1,284 @@
|
||||
// File: Voxel_CollisionDetection.cxx
|
||||
// Created: Mon July 16 12:13:45 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_CollisionDetection.ixx>
|
||||
#include <Voxel_FastConverter.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
||||
|
||||
|
||||
Voxel_CollisionDetection::Voxel_CollisionDetection()
|
||||
:myDeflection(0.1),
|
||||
myNbX(100),
|
||||
myNbY(100),
|
||||
myNbZ(100),
|
||||
myUsageOfVolume(Standard_False),
|
||||
myKeepCollisions(Standard_False),
|
||||
myXLen(-1.0),
|
||||
myYLen(-1.0),
|
||||
myZLen(-1.0),
|
||||
myVoxels(0),
|
||||
myHasCollisions(Standard_False)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Voxel_CollisionDetection::Voxel_CollisionDetection(const Standard_Real deflection,
|
||||
const Standard_Integer nbx,
|
||||
const Standard_Integer nby,
|
||||
const Standard_Integer nbz)
|
||||
:myDeflection(deflection),
|
||||
myNbX(nbx),
|
||||
myNbY(nby),
|
||||
myNbZ(nbz),
|
||||
myUsageOfVolume(Standard_False),
|
||||
myKeepCollisions(Standard_False),
|
||||
myXLen(-1.0),
|
||||
myYLen(-1.0),
|
||||
myZLen(-1.0),
|
||||
myVoxels(0),
|
||||
myHasCollisions(Standard_False)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_CollisionDetection::Destroy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
Standard_Integer Voxel_CollisionDetection::AddShape(const TopoDS_Shape& shape)
|
||||
{
|
||||
Clear();
|
||||
myShapes.Append(shape);
|
||||
return myShapes.Extent();
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_CollisionDetection::ReplaceShape(const Standard_Integer ishape,
|
||||
const TopoDS_Shape& shape)
|
||||
{
|
||||
if (ishape == 1)
|
||||
{
|
||||
myShapes.RemoveFirst();
|
||||
myShapes.Prepend(shape);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Integer i = 1;
|
||||
Standard_Boolean is_replaced = Standard_False;
|
||||
TopTools_ListIteratorOfListOfShape itr(myShapes);
|
||||
for (; itr.More(); itr.Next(), i++)
|
||||
{
|
||||
if (i == ishape)
|
||||
{
|
||||
myShapes.Remove(itr);
|
||||
myShapes.InsertBefore(shape, itr);
|
||||
is_replaced = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is_replaced;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::SetDeflection(const Standard_Real deflection)
|
||||
{
|
||||
myDeflection = deflection;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::SetNbVoxels(const Standard_Integer nbx,
|
||||
const Standard_Integer nby,
|
||||
const Standard_Integer nbz)
|
||||
{
|
||||
myNbX = nbx;
|
||||
myNbY = nby;
|
||||
myNbZ = nbz;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::SetBoundaryBox(const Bnd_Box& box)
|
||||
{
|
||||
if (box.IsVoid())
|
||||
return;
|
||||
|
||||
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
myX = xmin;
|
||||
myY = ymin;
|
||||
myZ = zmin;
|
||||
|
||||
myXLen = xmax - xmin;
|
||||
myYLen = ymax - ymin;
|
||||
myZLen = zmax - zmin;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::SetUsageOfVolume(const Standard_Boolean usage)
|
||||
{
|
||||
myUsageOfVolume = usage;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::KeepCollisions(const Standard_Boolean keep)
|
||||
{
|
||||
myKeepCollisions = keep;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_CollisionDetection::Voxelize(const Standard_Integer ishape)
|
||||
{
|
||||
// Check the arguments
|
||||
if (myNbX <= 0 || myNbY <= 0 || myNbZ <= 0)
|
||||
return Standard_False;
|
||||
|
||||
// Calculate the boundary box of the shapes to define the size of voxels.
|
||||
// This code is called only if the user didn't define the boundary box himself.
|
||||
if (myXLen < 0.0)
|
||||
{
|
||||
Bnd_Box B, b;
|
||||
TopTools_ListIteratorOfListOfShape itrs(myShapes);
|
||||
for (; itrs.More(); itrs.Next())
|
||||
{
|
||||
TopoDS_Shape S = itrs.Value();
|
||||
BRepBndLib::Add(S, b);
|
||||
B.Add(b);
|
||||
}
|
||||
SetBoundaryBox(B);
|
||||
}
|
||||
|
||||
// Voxelize the shapes
|
||||
Standard_Integer progress, ithread = 1, i = 1;
|
||||
TopTools_ListIteratorOfListOfShape itrs(myShapes);
|
||||
for (; itrs.More(); itrs.Next(), i++)
|
||||
{
|
||||
if (ishape != -1 && i != ishape)
|
||||
continue;
|
||||
|
||||
if (!myVoxels)
|
||||
myVoxels = (Standard_Address) new Voxel_BoolDS[myShapes.Extent()];
|
||||
Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[i - 1];
|
||||
if (!CheckVoxels(voxels))
|
||||
{
|
||||
voxels.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
voxels.SetZero();
|
||||
}
|
||||
|
||||
TopoDS_Shape S = itrs.Value();
|
||||
Voxel_FastConverter voxelizer(S, voxels, myDeflection, myNbX, myNbY, myNbZ, 1 /*number of threads */);
|
||||
if (!voxelizer.Convert(progress, ithread))
|
||||
return Standard_False;
|
||||
if (myUsageOfVolume && !voxelizer.FillInVolume(1, ithread))
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_CollisionDetection::Compute()
|
||||
{
|
||||
myHasCollisions = Standard_False;
|
||||
|
||||
// Check voxels of shapes
|
||||
if (!myVoxels)
|
||||
return Standard_False;
|
||||
Standard_Integer ishape = 0, nb_shapes = myShapes.Extent();
|
||||
for (; ishape < nb_shapes; ishape++)
|
||||
{
|
||||
Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[ishape];
|
||||
if (!CheckVoxels(voxels))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the resulting voxels
|
||||
Standard_Boolean created = Standard_False;
|
||||
if (!CheckVoxels(myCollisions))
|
||||
{
|
||||
// Create 0-voxels for the result, if it is needed.
|
||||
created = Standard_True;
|
||||
myCollisions.Init(myX, myY, myZ, myXLen, myYLen, myZLen, myNbX, myNbY, myNbZ);
|
||||
}
|
||||
|
||||
// Nullify the voxels of the result (it corresponds to the state of no collisions).
|
||||
if (!myKeepCollisions && !created)
|
||||
{
|
||||
myCollisions.SetZero();
|
||||
}
|
||||
|
||||
// Check collisions
|
||||
if (nb_shapes)
|
||||
{
|
||||
Standard_Integer ix, iy, iz;
|
||||
Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[0]; // 1st shape
|
||||
for (ix = 0; ix < myNbX; ix++)
|
||||
{
|
||||
for (iy = 0; iy < myNbY; iy++)
|
||||
{
|
||||
for (iz = 0; iz < myNbZ; iz++)
|
||||
{
|
||||
if (voxels.Get(ix, iy, iz))
|
||||
{
|
||||
for (ishape = 1; ishape < nb_shapes; ishape++) // start with second shape
|
||||
{
|
||||
Voxel_BoolDS& voxels = ((Voxel_BoolDS*)myVoxels)[ishape];
|
||||
if (voxels.Get(ix, iy, iz))
|
||||
{
|
||||
myCollisions.Set(ix, iy, iz, Standard_True);
|
||||
if (!myHasCollisions)
|
||||
{
|
||||
myHasCollisions = Standard_True;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_CollisionDetection::HasCollisions() const
|
||||
{
|
||||
return myHasCollisions;
|
||||
}
|
||||
|
||||
const Voxel_BoolDS& Voxel_CollisionDetection::GetCollisions() const
|
||||
{
|
||||
return myCollisions;
|
||||
}
|
||||
|
||||
void Voxel_CollisionDetection::Clear()
|
||||
{
|
||||
if (myVoxels)
|
||||
{
|
||||
delete ((Voxel_BoolDS*)myVoxels);
|
||||
myVoxels = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_CollisionDetection::CheckVoxels(const Voxel_BoolDS& voxels) const
|
||||
{
|
||||
if (fabs(voxels.GetX() - myX) > Precision::Confusion() ||
|
||||
fabs(voxels.GetY() - myY) > Precision::Confusion() ||
|
||||
fabs(voxels.GetZ() - myZ) > Precision::Confusion() ||
|
||||
fabs(voxels.GetXLen() - myXLen) > Precision::Confusion() ||
|
||||
fabs(voxels.GetYLen() - myYLen) > Precision::Confusion() ||
|
||||
fabs(voxels.GetZLen() - myZLen) > Precision::Confusion() ||
|
||||
voxels.GetNbX() != myNbX ||
|
||||
voxels.GetNbY() != myNbY ||
|
||||
voxels.GetNbZ() != myNbZ)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
74
src/Voxel/Voxel_ColorDS.cdl
Executable file
74
src/Voxel/Voxel_ColorDS.cdl
Executable file
@@ -0,0 +1,74 @@
|
||||
-- File: Voxel_BoolDS.cdl
|
||||
-- Created: Sun May 08 12:53:45 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class ColorDS from Voxel inherits DS from Voxel
|
||||
|
||||
---Purpose: A 3D voxel model keeping 4 bits for each voxel (one of 16 colors).
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns ColorDS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns ColorDS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is redefined virtual;
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of the voxel model.
|
||||
|
||||
SetZero(me : in out);
|
||||
---Purpose: The method sets all values equal to 0 (false) and
|
||||
-- releases the memory.
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
data : Byte from Standard);
|
||||
---Purpose: Defines a value for voxel with co-ordinates (ix, iy, iz).
|
||||
-- Only the first four bits are used!
|
||||
-- Initial state of the model is so that all voxels have value 0x0000,
|
||||
-- and this data doesn't occupy memory.
|
||||
-- Memory for data is allocating during setting non-zero values (0x0101, for example).
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the value of voxel with co-ordinates (ix, iy, iz).
|
||||
returns Byte from Standard;
|
||||
|
||||
end ColorDS;
|
163
src/Voxel/Voxel_ColorDS.cxx
Executable file
163
src/Voxel/Voxel_ColorDS.cxx
Executable file
@@ -0,0 +1,163 @@
|
||||
// File: Voxel_ColorDS.cxx
|
||||
// Created: Mon May 08 12:36:31 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_ColorDS.ixx>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static Standard_Byte gbits[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
||||
static Standard_Byte gnbits[8] = {255-1, 255-2, 255-4, 255-8, 255-16, 255-32, 255-64, 255-128};
|
||||
|
||||
// Empty constructor
|
||||
Voxel_ColorDS::Voxel_ColorDS():Voxel_DS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_ColorDS::Voxel_ColorDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
:Voxel_DS()
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_ColorDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
if (!myNbX || !myNbY || !myNbZ)
|
||||
return;
|
||||
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 2.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
myData = (Standard_Address) calloc(nb_slices, sizeof(Standard_Byte*));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_ColorDS::Destroy()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
SetZero();
|
||||
free((Standard_Byte**)myData);
|
||||
myData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_ColorDS::SetZero()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 2.0));
|
||||
Standard_Integer ix = 0, nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
for (; ix < nb_slices; ix++)
|
||||
{
|
||||
if (((Standard_Byte**)myData)[ix])
|
||||
{
|
||||
free(((Standard_Byte**)myData)[ix]);
|
||||
((Standard_Byte**)myData)[ix] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Access to the boolean information attached to a particular voxel:
|
||||
// Info: (ix >= 0 && ix < theNb_x), etc.
|
||||
void Voxel_ColorDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Byte data)
|
||||
{
|
||||
Standard_Integer ibit = 4 * (ix + myNbX * iy + myNbXY * iz);
|
||||
Standard_Integer islice = ibit >> 8;
|
||||
|
||||
if (!data && !((Standard_Byte**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
{
|
||||
((Standard_Byte**)myData)[islice] = (Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
|
||||
// Index within 32 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 8);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value":
|
||||
// It is either 0 (first part of the byte) or 2 (second part of the byte)
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
// Set data
|
||||
Standard_Integer i = 0, j = 0, nb = 4; // first part of byte
|
||||
if (shift == 4)
|
||||
{
|
||||
// second part of byte
|
||||
i = 4;
|
||||
nb = 8;
|
||||
}
|
||||
|
||||
for (; i < nb; i++, j++)
|
||||
{
|
||||
if (data & gbits[j]) // if j-th bit is 1
|
||||
{
|
||||
value |= gbits[i]; // set 1 to the i-th bit
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= gnbits[i]; // set 0 to the i-th bit
|
||||
}
|
||||
}
|
||||
|
||||
((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte] = value;
|
||||
}
|
||||
|
||||
Standard_Byte Voxel_ColorDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Byte ret = 0;
|
||||
Standard_Integer ibit = 4 * (ix + myNbX * iy + myNbXY * iz);
|
||||
Standard_Integer islice = ibit >> 8;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
return ret;
|
||||
|
||||
// Index within 8 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 8);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
// Return a byte with 4 first bits filled-in by the value.
|
||||
Standard_Integer i = 0, j = 0, nb = 4; // first part of byte
|
||||
if (shift == 4)
|
||||
{
|
||||
// second part of byte
|
||||
i = 4;
|
||||
nb = 8;
|
||||
}
|
||||
|
||||
for (; i < nb; i++, j++)
|
||||
{
|
||||
if (value & gbits[i]) // if i-th bit is 1
|
||||
{
|
||||
ret |= gbits[j]; // set 1 to the j-th bit
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
134
src/Voxel/Voxel_DS.cdl
Executable file
134
src/Voxel/Voxel_DS.cdl
Executable file
@@ -0,0 +1,134 @@
|
||||
-- File: Voxel_DS.cdl
|
||||
-- Created: Sun May 07 14:53:46 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class DS from Voxel
|
||||
|
||||
---Purpose: A base class for all voxel data structures.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns DS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns DS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is virtual;
|
||||
|
||||
---Purpose: The methods below return initial data of the voxel model.
|
||||
GetX (me) returns Real from Standard;
|
||||
GetY (me) returns Real from Standard;
|
||||
GetZ (me) returns Real from Standard;
|
||||
GetXLen(me) returns Real from Standard;
|
||||
GetYLen(me) returns Real from Standard;
|
||||
GetZLen(me) returns Real from Standard;
|
||||
GetNbX (me) returns Integer from Standard;
|
||||
GetNbY (me) returns Integer from Standard;
|
||||
GetNbZ (me) returns Integer from Standard;
|
||||
|
||||
GetCenter(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
xc : out Real from Standard;
|
||||
yc : out Real from Standard;
|
||||
zc : out Real from Standard);
|
||||
---Purpose: Returns the center point of a voxel with co-ordinates (ix, iy, iz).
|
||||
|
||||
GetVoxel(me;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
ix : out Integer from Standard;
|
||||
iy : out Integer from Standard;
|
||||
iz : out Integer from Standard)
|
||||
---Purpose: Finds a voxel corresponding to a 3D point.
|
||||
-- Returns true if it is found.
|
||||
returns Boolean from Standard;
|
||||
|
||||
GetVoxelX(me;
|
||||
x : Real from Standard;
|
||||
ix : out Integer from Standard)
|
||||
---Purpose: Returns x-index of a voxel corresponding to x-coordinate.
|
||||
returns Boolean from Standard;
|
||||
|
||||
GetVoxelY(me;
|
||||
y : Real from Standard;
|
||||
iy : out Integer from Standard)
|
||||
---Purpose: Returns y-index of a voxel corresponding to y-coordinate.
|
||||
returns Boolean from Standard;
|
||||
|
||||
GetVoxelZ(me;
|
||||
z : Real from Standard;
|
||||
iz : out Integer from Standard)
|
||||
---Purpose: Returns z-index of a voxel corresponding to z-coordinate.
|
||||
returns Boolean from Standard;
|
||||
|
||||
fields
|
||||
|
||||
-- Flag (1 or 0) attached to each voxel (BoolDS).
|
||||
-- 4 bits attached to each voxel (ColorDS).
|
||||
-- Etc.
|
||||
myData : Address from Standard is protected;
|
||||
|
||||
-- Start point of the cube of voxels.
|
||||
myX : Real from Standard is protected;
|
||||
myY : Real from Standard is protected;
|
||||
myZ : Real from Standard is protected;
|
||||
|
||||
-- Lengths of cube of voxels along X, Y and Z directions.
|
||||
myXLen : Real from Standard is protected;
|
||||
myYLen : Real from Standard is protected;
|
||||
myZLen : Real from Standard is protected;
|
||||
|
||||
-- Number of voxels along X, Y and Z directions.
|
||||
myNbX : Integer from Standard is protected;
|
||||
myNbY : Integer from Standard is protected;
|
||||
myNbZ : Integer from Standard is protected;
|
||||
|
||||
--- Optimization data.
|
||||
myNbXY : Integer from Standard is protected;
|
||||
myDX : Real from Standard is protected;
|
||||
myDY : Real from Standard is protected;
|
||||
myDZ : Real from Standard is protected;
|
||||
myHalfDX : Real from Standard is protected;
|
||||
myHalfDY : Real from Standard is protected;
|
||||
myHalfDZ : Real from Standard is protected;
|
||||
|
||||
friends
|
||||
|
||||
-- Gives access to myData inorder to make reading/writing much faster.
|
||||
class Writer from Voxel,
|
||||
class Reader from Voxel
|
||||
|
||||
end DS;
|
172
src/Voxel/Voxel_DS.cxx
Executable file
172
src/Voxel/Voxel_DS.cxx
Executable file
@@ -0,0 +1,172 @@
|
||||
// File: Voxel_DS.cxx
|
||||
// Created: Mon May 11 13:46:35 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_DS.ixx>
|
||||
|
||||
// Empty constructor
|
||||
Voxel_DS::Voxel_DS()
|
||||
:myData(0),
|
||||
myX(0.0),myY(0.0),myZ(0.0),
|
||||
myXLen(0.0),myYLen(0.0),myZLen(0.0),
|
||||
myNbX(0),myNbY(0),myNbZ(0),
|
||||
myNbXY(0),myDX(0.0),myDY(0.0),myDZ(0.0),
|
||||
myHalfDX(0.0),myHalfDY(0.0),myHalfDZ(0.0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_DS::Voxel_DS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_DS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
myX = x;
|
||||
myY = y;
|
||||
myZ = z;
|
||||
myXLen = xlen;
|
||||
myYLen = ylen;
|
||||
myZLen = zlen;
|
||||
myNbX = nbx;
|
||||
myNbY = nby;
|
||||
myNbZ = nbz;
|
||||
myNbXY = myNbX * myNbY;
|
||||
myDX = myXLen / (Standard_Real) myNbX;
|
||||
myDY = myYLen / (Standard_Real) myNbY;
|
||||
myDZ = myZLen / (Standard_Real) myNbZ;
|
||||
myHalfDX = myDX / 2.0;
|
||||
myHalfDY = myDY / 2.0;
|
||||
myHalfDZ = myDZ / 2.0;
|
||||
}
|
||||
|
||||
// Get the initial information on voxels
|
||||
Standard_Real Voxel_DS::GetX() const
|
||||
{
|
||||
return myX;
|
||||
}
|
||||
|
||||
Standard_Real Voxel_DS::GetY() const
|
||||
{
|
||||
return myY;
|
||||
}
|
||||
|
||||
Standard_Real Voxel_DS::GetZ() const
|
||||
{
|
||||
return myZ;
|
||||
}
|
||||
|
||||
Standard_Real Voxel_DS::GetXLen() const
|
||||
{
|
||||
return myXLen;
|
||||
}
|
||||
|
||||
Standard_Real Voxel_DS::GetYLen() const
|
||||
{
|
||||
return myYLen;
|
||||
}
|
||||
|
||||
Standard_Real Voxel_DS::GetZLen() const
|
||||
{
|
||||
return myZLen;
|
||||
}
|
||||
|
||||
Standard_Integer Voxel_DS::GetNbX() const
|
||||
{
|
||||
return myNbX;
|
||||
}
|
||||
|
||||
Standard_Integer Voxel_DS::GetNbY() const
|
||||
{
|
||||
return myNbY;
|
||||
}
|
||||
|
||||
Standard_Integer Voxel_DS::GetNbZ() const
|
||||
{
|
||||
return myNbZ;
|
||||
}
|
||||
|
||||
void Voxel_DS::GetCenter(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
Standard_Real& xc, Standard_Real& yc, Standard_Real& zc) const
|
||||
{
|
||||
xc = myX + ix * myDX + myHalfDX;
|
||||
yc = myY + iy * myDY + myHalfDY;
|
||||
zc = myZ + iz * myDZ + myHalfDZ;
|
||||
}
|
||||
|
||||
// The method uses a chordial approach to find the index of voxel by co-ordinate.
|
||||
static Standard_Integer findIndex(const Standard_Real xstart, const Standard_Real dx,
|
||||
const Standard_Integer ix1, const Standard_Integer ix2,
|
||||
const Standard_Real x)
|
||||
{
|
||||
if (ix2 - ix1 < 2)
|
||||
{
|
||||
if (x < xstart + ix2 * dx)
|
||||
return ix1;
|
||||
return ix2;
|
||||
}
|
||||
|
||||
// Middle index
|
||||
const Standard_Integer ixm = (ix1 + ix2) / 2;
|
||||
|
||||
// Check if it is in the first half:
|
||||
if (x >= xstart + ix1 * dx && x < xstart + ixm * dx)
|
||||
{
|
||||
return findIndex(xstart, dx, ix1, ixm, x);
|
||||
}
|
||||
|
||||
return findIndex(xstart, dx, ixm, ix2, x);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_DS::GetVoxel(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
Standard_Integer& ix, Standard_Integer& iy, Standard_Integer& iz) const
|
||||
{
|
||||
// X
|
||||
if (!GetVoxelX(x, ix))
|
||||
return Standard_False;
|
||||
|
||||
// Y
|
||||
if (!GetVoxelY(y, iy))
|
||||
return Standard_False;
|
||||
|
||||
// Z
|
||||
return GetVoxelZ(z, iz);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_DS::GetVoxelX(const Standard_Real x,
|
||||
Standard_Integer& ix) const
|
||||
{
|
||||
// X
|
||||
if (x < myX || x > myX + myXLen)
|
||||
return Standard_False;
|
||||
ix = findIndex(myX, myXLen / (Standard_Real) myNbX, 0, myNbX - 1, x);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_DS::GetVoxelY(const Standard_Real y,
|
||||
Standard_Integer& iy) const
|
||||
{
|
||||
// Y
|
||||
if (y < myY || y > myY + myYLen)
|
||||
return Standard_False;
|
||||
iy = findIndex(myY, myYLen / (Standard_Real) myNbY, 0, myNbY - 1, y);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_DS::GetVoxelZ(const Standard_Real z,
|
||||
Standard_Integer& iz) const
|
||||
{
|
||||
// Z
|
||||
if (z < myZ || z > myZ + myZLen)
|
||||
return Standard_False;
|
||||
iz = findIndex(myZ, myZLen / (Standard_Real) myNbZ, 0, myNbZ - 1, z);
|
||||
return Standard_True;
|
||||
}
|
126
src/Voxel/Voxel_FastConverter.cdl
Executable file
126
src/Voxel/Voxel_FastConverter.cdl
Executable file
@@ -0,0 +1,126 @@
|
||||
-- File: Voxel_FastConverter.cdl
|
||||
-- Created: Mon May 30 12:14:12 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class FastConverter from Voxel
|
||||
|
||||
---Purpose: Converts a shape to voxel representation.
|
||||
-- It does it fast, but with less precision.
|
||||
-- Also, it doesn't fill-in volumic part of the shape.
|
||||
|
||||
uses
|
||||
|
||||
Pnt from gp,
|
||||
Pln from gp,
|
||||
Shape from TopoDS,
|
||||
BoolDS from Voxel,
|
||||
ColorDS from Voxel,
|
||||
ROctBoolDS from Voxel
|
||||
|
||||
is
|
||||
|
||||
Create(shape : Shape from TopoDS;
|
||||
voxels : out BoolDS from Voxel;
|
||||
delfection : Real from Standard = 0.1;
|
||||
nbx : Integer from Standard = 10;
|
||||
nby : Integer from Standard = 10;
|
||||
nbz : Integer from Standard = 10;
|
||||
nbthreads : Integer from Standard = 1)
|
||||
---Purpose: A constructor for conversion of a shape into a cube of boolean voxels.
|
||||
-- It allocates the voxels in memory.
|
||||
-- "nbthreads" defines the number of threads used to convert the shape.
|
||||
returns FastConverter from Voxel;
|
||||
|
||||
Create(shape : Shape from TopoDS;
|
||||
voxels : out ColorDS from Voxel;
|
||||
delfection : Real from Standard = 0.1;
|
||||
nbx : Integer from Standard = 10;
|
||||
nby : Integer from Standard = 10;
|
||||
nbz : Integer from Standard = 10;
|
||||
nbthreads : Integer from Standard = 1)
|
||||
---Purpose: A constructor for conversion of a shape into a cube of colored voxels.
|
||||
-- It allocates the voxels in memory.
|
||||
-- "nbthreads" defines the number of threads used to convert the shape.
|
||||
returns FastConverter from Voxel;
|
||||
|
||||
Create(shape : Shape from TopoDS;
|
||||
voxels : out ROctBoolDS from Voxel;
|
||||
delfection : Real from Standard = 0.1;
|
||||
nbx : Integer from Standard = 10;
|
||||
nby : Integer from Standard = 10;
|
||||
nbz : Integer from Standard = 10;
|
||||
nbthreads : Integer from Standard = 1)
|
||||
---Purpose: A constructor for conversion of a shape into a cube of boolean voxels
|
||||
-- split into 8 sub-voxels recursively.
|
||||
-- It allocates the voxels in memory.
|
||||
-- "nbthreads" defines the number of threads used to convert the shape.
|
||||
returns FastConverter from Voxel;
|
||||
|
||||
Convert(me : in out;
|
||||
progress : out Integer from Standard;
|
||||
ithread : Integer from Standard = 1)
|
||||
---Purpose: Converts a shape into a voxel representation.
|
||||
-- It sets to 0 the outside volume of the shape and
|
||||
-- 1 for surfacic part of the shape.
|
||||
-- "ithread" is the index of the thread for current call of ::Convert().
|
||||
-- Start numeration of "ithread" with 1, please.
|
||||
returns Boolean from Standard;
|
||||
|
||||
FillInVolume(me : in out;
|
||||
inner : Byte from Standard;
|
||||
ithread : Integer from Standard = 1)
|
||||
---Purpose: Fills-in volume of the shape by a value.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Private area
|
||||
-- ============
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor.
|
||||
|
||||
Init(me : in out)
|
||||
is private;
|
||||
|
||||
GetBndBox(me;
|
||||
p1 : Pnt from gp;
|
||||
p2 : Pnt from gp;
|
||||
p3 : Pnt from gp;
|
||||
xmin : out Real from Standard;
|
||||
ymin : out Real from Standard;
|
||||
zmin : out Real from Standard;
|
||||
xmax : out Real from Standard;
|
||||
ymax : out Real from Standard;
|
||||
zmax : out Real from Standard)
|
||||
is private;
|
||||
|
||||
ComputeVoxelsNearTriangle(me;
|
||||
plane : Pln from gp;
|
||||
p1 : Pnt from gp;
|
||||
p2 : Pnt from gp;
|
||||
p3 : Pnt from gp;
|
||||
hdiag : Real from Standard;
|
||||
ixmin : Integer from Standard;
|
||||
iymin : Integer from Standard;
|
||||
izmin : Integer from Standard;
|
||||
ixmax : Integer from Standard;
|
||||
iymax : Integer from Standard;
|
||||
izmax : Integer from Standard)
|
||||
is private;
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS;
|
||||
myVoxels : Address from Standard;
|
||||
myDeflection : Real from Standard;
|
||||
myIsBool : Integer from Standard; -- 0 - ColorDS, 1 - BoolDS, 2 - ROctBoolDS
|
||||
myNbX : Integer from Standard;
|
||||
myNbY : Integer from Standard;
|
||||
myNbZ : Integer from Standard;
|
||||
myNbThreads : Integer from Standard;
|
||||
myNbTriangles : Integer from Standard;
|
||||
|
||||
end FastConverter;
|
668
src/Voxel/Voxel_FastConverter.cxx
Executable file
668
src/Voxel/Voxel_FastConverter.cxx
Executable file
@@ -0,0 +1,668 @@
|
||||
// File: Voxel_FastConverter.cxx
|
||||
// Created: Mon May 30 17:55:14 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_FastConverter.ixx>
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepMesh.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include <gp_Lin2d.hxx>
|
||||
#include <gce_MakePln.hxx>
|
||||
|
||||
#include <ElSLib.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <IntAna2d_AnaIntersection.hxx>
|
||||
|
||||
// Printing the progress in stdout.
|
||||
//#define CONV_DUMP
|
||||
|
||||
Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape,
|
||||
Voxel_ROctBoolDS& voxels,
|
||||
const Standard_Real deflection,
|
||||
const Standard_Integer nbx,
|
||||
const Standard_Integer nby,
|
||||
const Standard_Integer nbz,
|
||||
const Standard_Integer nbthreads)
|
||||
:myShape(shape),myVoxels(&voxels),
|
||||
myDeflection(deflection),
|
||||
myNbX(nbx),myNbY(nby),myNbZ(nbz),
|
||||
myNbThreads(nbthreads),myIsBool(2),
|
||||
myNbTriangles(0)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape,
|
||||
Voxel_BoolDS& voxels,
|
||||
const Standard_Real deflection,
|
||||
const Standard_Integer nbx,
|
||||
const Standard_Integer nby,
|
||||
const Standard_Integer nbz,
|
||||
const Standard_Integer nbthreads)
|
||||
:myShape(shape),myVoxels(&voxels),
|
||||
myDeflection(deflection),
|
||||
myNbX(nbx),myNbY(nby),myNbZ(nbz),
|
||||
myNbThreads(nbthreads),myIsBool(1),
|
||||
myNbTriangles(0)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
Voxel_FastConverter::Voxel_FastConverter(const TopoDS_Shape& shape,
|
||||
Voxel_ColorDS& voxels,
|
||||
const Standard_Real deflection,
|
||||
const Standard_Integer nbx,
|
||||
const Standard_Integer nby,
|
||||
const Standard_Integer nbz,
|
||||
const Standard_Integer nbthreads)
|
||||
:myShape(shape),myVoxels(&voxels),
|
||||
myDeflection(deflection),
|
||||
myNbX(nbx),myNbY(nby),myNbZ(nbz),
|
||||
myNbThreads(nbthreads),myIsBool(0),
|
||||
myNbTriangles(0)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void Voxel_FastConverter::Init()
|
||||
{
|
||||
if (myShape.IsNull())
|
||||
return;
|
||||
if (myNbThreads < 1)
|
||||
return;
|
||||
|
||||
// Check number of splits.
|
||||
Voxel_DS* voxels = (Voxel_DS*) myVoxels;
|
||||
if (voxels->GetNbX() != myNbX || voxels->GetNbY() != myNbY || voxels->GetNbZ() != myNbZ)
|
||||
{
|
||||
// Compute boundary box of the shape
|
||||
Bnd_Box box;
|
||||
BRepBndLib::Add(myShape, box);
|
||||
|
||||
// Define the voxel model by means of the boundary box of shape
|
||||
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
// Initialize the voxels.
|
||||
if (myIsBool == 2)
|
||||
((Voxel_ROctBoolDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ);
|
||||
else if (myIsBool == 1)
|
||||
((Voxel_BoolDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ);
|
||||
else if (myIsBool == 0)
|
||||
((Voxel_ColorDS*) voxels)->Init(xmin, ymin, zmin, xmax - xmin, ymax - ymin, zmax - zmin, myNbX, myNbY, myNbZ);
|
||||
}
|
||||
|
||||
// Check presence of triangulation.
|
||||
TopLoc_Location L;
|
||||
Standard_Boolean triangulate = Standard_False;
|
||||
TopExp_Explorer expl(myShape, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next())
|
||||
{
|
||||
TopoDS_Face F = TopoDS::Face(expl.Current());
|
||||
Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L);
|
||||
if (T.IsNull() || fabs(T->Deflection() - myDeflection) > Precision::Confusion())
|
||||
{
|
||||
triangulate = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-create the triangulation.
|
||||
if (triangulate)
|
||||
{
|
||||
BRepMesh::Mesh(myShape, myDeflection);
|
||||
}
|
||||
|
||||
// Compute the number of triangles.
|
||||
myNbTriangles = 0;
|
||||
expl.Init(myShape, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next())
|
||||
{
|
||||
TopoDS_Face F = TopoDS::Face(expl.Current());
|
||||
Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L);
|
||||
myNbTriangles += T->NbTriangles();
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_FastConverter::Destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_FastConverter::Convert(Standard_Integer& progress,
|
||||
const Standard_Integer ithread)
|
||||
{
|
||||
if (ithread == 1)
|
||||
progress = 0;
|
||||
#ifdef CONV_DUMP
|
||||
if (ithread == 1)
|
||||
printf("Progress = %d \r", progress);
|
||||
#endif
|
||||
|
||||
if (myNbX <= 0 || myNbY <= 0 || myNbZ <= 0)
|
||||
return Standard_False;
|
||||
|
||||
// Half of diagonal of a voxel
|
||||
Voxel_DS* ds = (Voxel_DS*) myVoxels;
|
||||
Standard_Real dx = ds->GetXLen() / (Standard_Real) ds->GetNbX(),
|
||||
dy = ds->GetYLen() / (Standard_Real) ds->GetNbY(),
|
||||
dz = ds->GetZLen() / (Standard_Real) ds->GetNbZ();
|
||||
Standard_Real hdiagonal = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
hdiagonal /= 2.0;
|
||||
|
||||
// Compute the scope of triangles for current thread
|
||||
Standard_Integer start_thread_triangle = 1, end_thread_triangle = myNbTriangles, ithread_triangle = 0;
|
||||
start_thread_triangle = (ithread - 1) * (myNbTriangles / myNbThreads) + 1;
|
||||
end_thread_triangle = (ithread - 0) * (myNbTriangles / myNbThreads);
|
||||
|
||||
// Convert
|
||||
TopLoc_Location L;
|
||||
Standard_Integer iprogress = 0, prev_progress = 0;
|
||||
Standard_Integer n1, n2, n3;
|
||||
Standard_Integer ixmin, iymin, izmin, ixmax, iymax, izmax;
|
||||
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
TopExp_Explorer expl(myShape, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next())
|
||||
{
|
||||
TopoDS_Face F = TopoDS::Face(expl.Current());
|
||||
Handle(Poly_Triangulation) T = BRep_Tool::Triangulation(F, L);
|
||||
|
||||
gp_Trsf trsf;
|
||||
Standard_Boolean transform = !L.IsIdentity();
|
||||
if (transform)
|
||||
trsf = L.Transformation();
|
||||
|
||||
const TColgp_Array1OfPnt& nodes = T->Nodes();
|
||||
const Poly_Array1OfTriangle& triangles = T->Triangles();
|
||||
Standard_Integer itriangle = triangles.Lower(), nb_triangles = triangles.Upper();
|
||||
for (; itriangle <= nb_triangles; itriangle++)
|
||||
{
|
||||
ithread_triangle++;
|
||||
if (ithread_triangle < start_thread_triangle || ithread_triangle > end_thread_triangle)
|
||||
continue;
|
||||
|
||||
const Poly_Triangle& t = triangles.Value(itriangle);
|
||||
t.Get(n1, n2, n3);
|
||||
gp_Pnt p1 = nodes.Value(n1);
|
||||
gp_Pnt p2 = nodes.Value(n2);
|
||||
gp_Pnt p3 = nodes.Value(n3);
|
||||
if (transform)
|
||||
{
|
||||
p1.Transform(trsf);
|
||||
p2.Transform(trsf);
|
||||
p3.Transform(trsf);
|
||||
}
|
||||
|
||||
// Get boundary box of the triangle
|
||||
GetBndBox(p1, p2, p3, xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
// Find the range of voxels inside the boudary box of the triangle.
|
||||
if (!ds->GetVoxel(xmin, ymin, zmin, ixmin, iymin, izmin))
|
||||
continue;
|
||||
if (!ds->GetVoxel(xmax, ymax, zmax, ixmax, iymax, izmax))
|
||||
continue;
|
||||
|
||||
// Refuse voxels for whom distance from their center to plane of triangle is greater than half of diagonal.
|
||||
// Make a line from center of each voxel to the center of triangle and
|
||||
// compute intersection of the line with sides of triangle.
|
||||
// Refuse the voxel in case of intersection.
|
||||
gce_MakePln mkPlane(p1, p2, p3);
|
||||
if (!mkPlane.IsDone())
|
||||
continue;
|
||||
gp_Pln plane = mkPlane.Value();
|
||||
ComputeVoxelsNearTriangle(plane, p1, p2, p3, hdiagonal, ixmin, iymin, izmin, ixmax, iymax, izmax);
|
||||
|
||||
// Progress
|
||||
if (ithread == 1)
|
||||
{
|
||||
iprogress++;
|
||||
progress = (Standard_Integer) ( (Standard_Real) iprogress / (Standard_Real) myNbTriangles * 100.0 );
|
||||
}
|
||||
#ifdef CONV_DUMP
|
||||
if (ithread == 1 && prev_progress != progress)
|
||||
{
|
||||
printf("Progress = %d \r", progress);
|
||||
prev_progress = progress;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // iteration of triangles
|
||||
} // iteration of faces
|
||||
|
||||
if (ithread == 1)
|
||||
progress = 100;
|
||||
#ifdef CONV_DUMP
|
||||
if (ithread == 1)
|
||||
printf("Progress = %d \r", progress);
|
||||
#endif
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_FastConverter::FillInVolume(const Standard_Byte inner,
|
||||
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;
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
volume = !volume;
|
||||
}
|
||||
prev_surface = surface;
|
||||
}
|
||||
if (volume)
|
||||
continue;
|
||||
|
||||
// Fill-in the volume.
|
||||
volume = Standard_False;
|
||||
surface = Standard_False;
|
||||
prev_surface = 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)
|
||||
{
|
||||
volume = !volume;
|
||||
}
|
||||
if (volume && !surface)
|
||||
{
|
||||
(myIsBool == 1) ? ((Voxel_BoolDS*)myVoxels)->Set(ix, iy, iz, inner) :
|
||||
((Voxel_ColorDS*)myVoxels)->Set(ix, iy, iz, inner);
|
||||
}
|
||||
prev_surface = surface;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set value of interbal voxels to 0 ("inner" = 0)
|
||||
Standard_Boolean next_surface;
|
||||
for (ix = 0; ix < nbx; ix++)
|
||||
{
|
||||
for (iy = 0; iy < nby; iy++)
|
||||
{
|
||||
volume = Standard_False;
|
||||
surface = Standard_False;
|
||||
prev_surface = Standard_False;
|
||||
next_surface = 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)
|
||||
{
|
||||
volume = !volume;
|
||||
}
|
||||
if (volume && iz + 1 < nbz)
|
||||
{
|
||||
next_surface = (myIsBool == 1) ?
|
||||
((Voxel_BoolDS*)myVoxels)->Get(ix, iy, iz + 1) == Standard_True :
|
||||
((Voxel_ColorDS*)myVoxels)->Get(ix, iy, iz + 1) > 0;
|
||||
}
|
||||
if (volume && prev_surface == surface && next_surface)
|
||||
{
|
||||
(myIsBool == 1) ? ((Voxel_BoolDS*)myVoxels)->Set(ix, iy, iz, inner) :
|
||||
((Voxel_ColorDS*)myVoxels)->Set(ix, iy, iz, inner);
|
||||
}
|
||||
prev_surface = surface;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
void Voxel_FastConverter::GetBndBox(const gp_Pnt& p1,
|
||||
const gp_Pnt& p2,
|
||||
const gp_Pnt& p3,
|
||||
Standard_Real& xmin,
|
||||
Standard_Real& ymin,
|
||||
Standard_Real& zmin,
|
||||
Standard_Real& xmax,
|
||||
Standard_Real& ymax,
|
||||
Standard_Real& zmax) const
|
||||
{
|
||||
// P1:
|
||||
xmin = p1.X();
|
||||
ymin = p1.Y();
|
||||
zmin = p1.Z();
|
||||
xmax = p1.X();
|
||||
ymax = p1.Y();
|
||||
zmax = p1.Z();
|
||||
// P2:
|
||||
if (xmin > p2.X())
|
||||
xmin = p2.X();
|
||||
if (ymin > p2.Y())
|
||||
ymin = p2.Y();
|
||||
if (zmin > p2.Z())
|
||||
zmin = p2.Z();
|
||||
if (xmax < p2.X())
|
||||
xmax = p2.X();
|
||||
if (ymax < p2.Y())
|
||||
ymax = p2.Y();
|
||||
if (zmax < p2.Z())
|
||||
zmax = p2.Z();
|
||||
// P3:
|
||||
if (xmin > p3.X())
|
||||
xmin = p3.X();
|
||||
if (ymin > p3.Y())
|
||||
ymin = p3.Y();
|
||||
if (zmin > p3.Z())
|
||||
zmin = p3.Z();
|
||||
if (xmax < p3.X())
|
||||
xmax = p3.X();
|
||||
if (ymax < p3.Y())
|
||||
ymax = p3.Y();
|
||||
if (zmax < p3.Z())
|
||||
zmax = p3.Z();
|
||||
}
|
||||
|
||||
// This method is copied from Voxel_ShapeIntersector.cxx
|
||||
static Standard_Boolean mayIntersect(const gp_Pnt2d& p11, const gp_Pnt2d& p12,
|
||||
const gp_Pnt2d& p21, const gp_Pnt2d& p22)
|
||||
{
|
||||
if (p11.X() > p21.X() && p11.X() > p22.X() && p12.X() > p21.X() && p12.X() > p22.X())
|
||||
return Standard_False;
|
||||
if (p11.X() < p21.X() && p11.X() < p22.X() && p12.X() < p21.X() && p12.X() < p22.X())
|
||||
return Standard_False;
|
||||
if (p11.Y() > p21.Y() && p11.Y() > p22.Y() && p12.Y() > p21.Y() && p12.Y() > p22.Y())
|
||||
return Standard_False;
|
||||
if (p11.Y() < p21.Y() && p11.Y() < p22.Y() && p12.Y() < p21.Y() && p12.Y() < p22.Y())
|
||||
return Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
void Voxel_FastConverter::ComputeVoxelsNearTriangle(const gp_Pln& plane,
|
||||
const gp_Pnt& p1,
|
||||
const gp_Pnt& p2,
|
||||
const gp_Pnt& p3,
|
||||
const Standard_Real hdiagonal,
|
||||
const Standard_Integer ixmin,
|
||||
const Standard_Integer iymin,
|
||||
const Standard_Integer izmin,
|
||||
const Standard_Integer ixmax,
|
||||
const Standard_Integer iymax,
|
||||
const Standard_Integer izmax) const
|
||||
{
|
||||
gp_Pnt pc;
|
||||
Standard_Real xc, yc, zc, uc, vc, u1, v1, u2, v2, u3, v3;
|
||||
Standard_Integer ix, iy, iz;
|
||||
IntAna2d_AnaIntersection intersector2d;
|
||||
|
||||
// Project points of triangle onto the plane
|
||||
ElSLib::Parameters(plane, p1, u1, v1);
|
||||
ElSLib::Parameters(plane, p2, u2, v2);
|
||||
ElSLib::Parameters(plane, p3, u3, v3);
|
||||
|
||||
// Make lines of triangle
|
||||
gp_Pnt2d p2d1(u1, v1), p2d2(u2, v2), p2d3(u3, v3), p2dt((u1+u2+u3)/3.0,(v1+v2+v3)/3.0), p2dc;
|
||||
gp_Vec2d v2d12(p2d1, p2d2), v2d23(p2d2, p2d3), v2d31(p2d3, p2d1);
|
||||
gp_Lin2d L1(p2d1, v2d12), L2(p2d2, v2d23), L3(p2d3, v2d31), Lv;
|
||||
Standard_Real d1 = p2d1.Distance(p2d2) - Precision::Confusion(),
|
||||
d2 = p2d2.Distance(p2d3) - Precision::Confusion(),
|
||||
d3 = p2d3.Distance(p2d1) - Precision::Confusion(), dv;
|
||||
|
||||
Voxel_DS* ds = (Voxel_DS*) myVoxels;
|
||||
for (ix = ixmin; ix <= ixmax; ix++)
|
||||
{
|
||||
for (iy = iymin; iy <= iymax; iy++)
|
||||
{
|
||||
for (iz = izmin; iz <= izmax; iz++)
|
||||
{
|
||||
ds->GetCenter(ix, iy, iz, xc, yc, zc);
|
||||
pc.SetCoord(xc, yc, zc);
|
||||
if (plane.Distance(pc) < hdiagonal)
|
||||
{
|
||||
ElSLib::Parameters(plane, pc, uc, vc);
|
||||
p2dc.SetCoord(uc, vc);
|
||||
|
||||
gp_Vec2d v2dct(p2dc, p2dt);
|
||||
dv = v2dct.Magnitude() - Precision::Confusion();
|
||||
Lv.SetLocation(p2dc);
|
||||
Lv.SetDirection(v2dct);
|
||||
|
||||
// Side 1:
|
||||
if (mayIntersect(p2d1, p2d2, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L1);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 2:
|
||||
if (mayIntersect(p2d2, p2d3, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L2);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 3:
|
||||
if (mayIntersect(p2d3, p2d1, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L3);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set positive value to this voxel:
|
||||
switch (myIsBool)
|
||||
{
|
||||
case 0:
|
||||
((Voxel_ColorDS*) myVoxels)->Set(ix, iy, iz, 15);
|
||||
break;
|
||||
case 1:
|
||||
((Voxel_BoolDS*) myVoxels)->Set(ix, iy, iz, Standard_True);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
//((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, Standard_True);
|
||||
|
||||
// Check intersection between the triangle & sub-voxels of the voxel.
|
||||
Standard_Real hdiagonal2 = hdiagonal / 2.0, hdiagonal4 = hdiagonal / 4.0;
|
||||
for (Standard_Integer i = 0; i < 8; i++)
|
||||
{
|
||||
((Voxel_ROctBoolDS*) myVoxels)->GetCenter(ix, iy, iz, i, xc, yc, zc);
|
||||
pc.SetCoord(xc, yc, zc);
|
||||
if (plane.Distance(pc) < hdiagonal2)
|
||||
{
|
||||
ElSLib::Parameters(plane, pc, uc, vc);
|
||||
p2dc.SetCoord(uc, vc);
|
||||
|
||||
gp_Vec2d v2dct(p2dc, p2dt);
|
||||
dv = v2dct.Magnitude() - Precision::Confusion();
|
||||
Lv.SetLocation(p2dc);
|
||||
Lv.SetDirection(v2dct);
|
||||
|
||||
// Side 1:
|
||||
if (mayIntersect(p2d1, p2d2, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L1);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 2:
|
||||
if (mayIntersect(p2d2, p2d3, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L2);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 3:
|
||||
if (mayIntersect(p2d3, p2d1, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L3);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, i, Standard_True);
|
||||
|
||||
// Check intersection between the triangle & sub-voxels of the sub-voxel.
|
||||
for (Standard_Integer j = 0; j < 8; j++)
|
||||
{
|
||||
((Voxel_ROctBoolDS*) myVoxels)->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
|
||||
pc.SetCoord(xc, yc, zc);
|
||||
if (plane.Distance(pc) < hdiagonal4)
|
||||
{
|
||||
ElSLib::Parameters(plane, pc, uc, vc);
|
||||
p2dc.SetCoord(uc, vc);
|
||||
|
||||
gp_Vec2d v2dct(p2dc, p2dt);
|
||||
dv = v2dct.Magnitude() - Precision::Confusion();
|
||||
Lv.SetLocation(p2dc);
|
||||
Lv.SetDirection(v2dct);
|
||||
|
||||
// Side 1:
|
||||
if (mayIntersect(p2d1, p2d2, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L1);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 2:
|
||||
if (mayIntersect(p2d2, p2d3, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L2);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side 3:
|
||||
if (mayIntersect(p2d3, p2d1, p2dc, p2dt))
|
||||
{
|
||||
intersector2d.Perform(Lv, L3);
|
||||
if (intersector2d.IsDone() && !intersector2d.ParallelElements() && intersector2d.NbPoints())
|
||||
{
|
||||
const IntAna2d_IntPoint& i2d = intersector2d.Point(1);
|
||||
Standard_Real param1 = i2d.ParamOnFirst();
|
||||
Standard_Real param2 = i2d.ParamOnSecond();
|
||||
if (param1 > Precision::Confusion() && param1 < dv &&
|
||||
param2 > Precision::Confusion() && param2 < d3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
((Voxel_ROctBoolDS*) myVoxels)->Set(ix, iy, iz, i, j, Standard_True);
|
||||
}
|
||||
} // End of "Check level 2".
|
||||
|
||||
}
|
||||
} // End of "Check level 1".
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
src/Voxel/Voxel_FloatDS.cdl
Executable file
74
src/Voxel/Voxel_FloatDS.cdl
Executable file
@@ -0,0 +1,74 @@
|
||||
-- File: Voxel_FloatDS.cdl
|
||||
-- Created: Sun May 15 13:21:34 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class FloatDS from Voxel inherits DS from Voxel
|
||||
|
||||
---Purpose: A 3D voxel model keeping a foating-point
|
||||
-- value for each voxel.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns FloatDS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns FloatDS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is redefined virtual;
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of the voxel model.
|
||||
|
||||
SetZero(me : in out);
|
||||
---Purpose: The method sets all values equal to 0 (false) and
|
||||
-- releases the memory.
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
data : ShortReal from Standard);
|
||||
---Purpose: Defines a value for voxel with co-ordinates (ix, iy, iz).
|
||||
-- Initial state of the model is so that all voxels have value 0.0f,
|
||||
-- and this data doesn't occupy memory.
|
||||
-- Memory for data is allocating during setting non-zero values.
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the value of voxel with co-ordinates (ix, iy, iz).
|
||||
returns ShortReal from Standard;
|
||||
|
||||
end FloatDS;
|
106
src/Voxel/Voxel_FloatDS.cxx
Executable file
106
src/Voxel/Voxel_FloatDS.cxx
Executable file
@@ -0,0 +1,106 @@
|
||||
// File: Voxel_FloatDS.cxx
|
||||
// Created: Mon May 15 13:38:43 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_FloatDS.ixx>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// Empty constructor
|
||||
Voxel_FloatDS::Voxel_FloatDS():Voxel_DS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_FloatDS::Voxel_FloatDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
:Voxel_DS()
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_FloatDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
if (!myNbX || !myNbY || !myNbZ)
|
||||
return;
|
||||
|
||||
Standard_Integer nb_floats = myNbXY * myNbZ;
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
|
||||
myData = (Standard_Address) calloc(nb_slices, sizeof(Standard_ShortReal*));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_FloatDS::Destroy()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
SetZero();
|
||||
free((Standard_ShortReal**)myData);
|
||||
myData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_FloatDS::SetZero()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
Standard_Integer nb_bytes = myNbXY * myNbZ;
|
||||
Standard_Integer ix = 0, nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
for (; ix < nb_slices; ix++)
|
||||
{
|
||||
if (((Standard_ShortReal**)myData)[ix])
|
||||
{
|
||||
free(((Standard_ShortReal**)myData)[ix]);
|
||||
((Standard_ShortReal**)myData)[ix] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Access to the floating-point information attached to a particular voxel:
|
||||
// Info: (ix >= 0 && ix < theNb_x), etc.
|
||||
void Voxel_FloatDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_ShortReal data)
|
||||
{
|
||||
Standard_Integer ifloat = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ifloat >> 5;
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Standard_ShortReal**)myData)[islice])
|
||||
{
|
||||
((Standard_ShortReal**)myData)[islice] =
|
||||
(Standard_ShortReal*) calloc(32/*number of floating values in slice*/, sizeof(Standard_ShortReal));
|
||||
}
|
||||
|
||||
// Index of start-byte of the value within the slice.
|
||||
Standard_Integer ivalue = ifloat - (islice << 5);
|
||||
|
||||
// Value (float)
|
||||
((Standard_ShortReal*)((Standard_ShortReal**)myData)[islice])[ivalue] = data;
|
||||
}
|
||||
|
||||
Standard_ShortReal Voxel_FloatDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ifloat = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ifloat >> 5;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Standard_ShortReal**)myData)[islice])
|
||||
return 0.0f;
|
||||
|
||||
// Index of start-byte of the value within the slice.
|
||||
Standard_Integer ivalue = ifloat - (islice << 5);
|
||||
|
||||
// Value (floating-point value)
|
||||
return ((Standard_ShortReal*)((Standard_ShortReal**)myData)[islice])[ivalue];
|
||||
}
|
130
src/Voxel/Voxel_OctBoolDS.cdl
Executable file
130
src/Voxel/Voxel_OctBoolDS.cdl
Executable file
@@ -0,0 +1,130 @@
|
||||
-- File: Voxel_OctBoolDS.cdl
|
||||
-- Created: Sun Aug 26 12:21:23 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class OctBoolDS from Voxel inherits DS from Voxel
|
||||
|
||||
---Purpose: A 3D voxel model keeping a boolean flag (1 or 0)
|
||||
-- value for each voxel, and having an opportunity to split each voxel
|
||||
-- into 8 sub-voxels.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns OctBoolDS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns OctBoolDS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is redefined virtual;
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of the voxel model.
|
||||
|
||||
SetZero(me : in out);
|
||||
---Purpose: The method sets all values equal to 0 (false) and
|
||||
-- releases the memory.
|
||||
|
||||
OptimizeMemory(me : in out);
|
||||
---Purpose: The method searches voxels with equal-value of sub-voxels
|
||||
-- and removes them (remaining the value for the voxel).
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
data : Boolean from Standard);
|
||||
---Purpose: Defines a value for voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is split into 8 sub-voxels, the split disappears.
|
||||
-- Initial state of the model is so that all voxels have value 0 (false),
|
||||
-- and this data doesn't occupy memory.
|
||||
-- Memory for data is allocating during setting non-zero values (true).
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct : Integer from Standard;
|
||||
data : Boolean from Standard);
|
||||
---Purpose: Defines a value for a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split into 8 sub-voxels yet, this method splits the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the value of voxel with co-ordinates (ix, iy, iz).
|
||||
-- Warning!: the returned value may not coincide with the value of its 8 sub-voxels.
|
||||
-- Use the method ::IsSplit() to check whether a voxel has sub-voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct : Integer from Standard)
|
||||
---Purpose: Returns the value of a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split, it returns the value of the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
returns Boolean from Standard;
|
||||
|
||||
IsSplit(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns true if the voxel is split into 8 sub-voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Private area
|
||||
-- ============
|
||||
|
||||
Split(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
is private;
|
||||
|
||||
UnSplit(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
is private;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
mySubVoxels : Address from Standard;
|
||||
|
||||
end OctBoolDS;
|
276
src/Voxel/Voxel_OctBoolDS.cxx
Executable file
276
src/Voxel/Voxel_OctBoolDS.cxx
Executable file
@@ -0,0 +1,276 @@
|
||||
// File: Voxel_OctBoolDS.cxx
|
||||
// Created: Mon Aug 27 15:33:27 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_OctBoolDS.ixx>
|
||||
#include <Voxel_TypeDef.hxx>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static Standard_Byte gbits[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
||||
static Standard_Byte gnbits[8] = {255-1, 255-2, 255-4, 255-8, 255-16, 255-32, 255-64, 255-128};
|
||||
static iXYZ xyz;
|
||||
|
||||
// Empty constructor
|
||||
Voxel_OctBoolDS::Voxel_OctBoolDS():Voxel_DS(),mySubVoxels(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_OctBoolDS::Voxel_OctBoolDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
:Voxel_DS(),mySubVoxels(0)
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_OctBoolDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
if (!myNbX || !myNbY || !myNbZ)
|
||||
return;
|
||||
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
myData = (Standard_Address) calloc(nb_slices, sizeof(Standard_Byte*));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_OctBoolDS::Destroy()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
SetZero();
|
||||
free((Standard_Byte**)myData);
|
||||
myData = 0;
|
||||
if (mySubVoxels)
|
||||
{
|
||||
delete (iXYZBool*)mySubVoxels;
|
||||
mySubVoxels = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_OctBoolDS::SetZero()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
Standard_Integer ix = 0, nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
for (; ix < nb_slices; ix++)
|
||||
{
|
||||
if (((Standard_Byte**)myData)[ix])
|
||||
{
|
||||
free(((Standard_Byte**)myData)[ix]);
|
||||
((Standard_Byte**)myData)[ix] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mySubVoxels)
|
||||
{
|
||||
iXYZBool* map = (iXYZBool*) mySubVoxels;
|
||||
map->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Access to the boolean information attached to a particular voxel:
|
||||
// Info: (ix >= 0 && ix < theNb_x), etc.
|
||||
void Voxel_OctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Boolean data)
|
||||
{
|
||||
// All 8 sub-voxels have the same value.
|
||||
// No need anymore to keep them in memory.
|
||||
if (IsSplit(ix, iy, iz))
|
||||
{
|
||||
UnSplit(ix, iy, iz);
|
||||
}
|
||||
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 6;
|
||||
|
||||
if (!data && !((Standard_Byte**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
{
|
||||
((Standard_Byte**)myData)[islice] = (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
|
||||
// Index within 8 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 6);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[shift]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[shift];
|
||||
else
|
||||
value &= gnbits[shift];
|
||||
((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_OctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct, const Standard_Boolean data)
|
||||
{
|
||||
// If the voxel is not split yet, do it now.
|
||||
if (!IsSplit(ix, iy, iz))
|
||||
{
|
||||
Split(ix, iy, iz);
|
||||
}
|
||||
|
||||
// Voxel
|
||||
xyz.ix = ix;
|
||||
xyz.iy = iy;
|
||||
xyz.iz = iz;
|
||||
|
||||
// Take the value
|
||||
Standard_Byte value = ((iXYZBool*)mySubVoxels)->Find(xyz);
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[ioct]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[ioct];
|
||||
else
|
||||
value &= gnbits[ioct];
|
||||
((iXYZBool*)mySubVoxels)->ChangeFind(xyz) = value;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_OctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 6;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Standard_Byte**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// Index within 8 bytes of the slice.
|
||||
Standard_Integer ibit_in_current_slice = ibit - (islice << 6);
|
||||
Standard_Integer ibyte = ibit_in_current_slice >> 3;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)myData)[islice])[ibyte];
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit_in_current_slice - (ibyte << 3);
|
||||
|
||||
return ((value & gbits[shift]) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_OctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct) const
|
||||
{
|
||||
// If the voxel is not split, return the value of the voxel.
|
||||
if (!IsSplit(ix, iy, iz))
|
||||
{
|
||||
return Get(ix, iy, iz);
|
||||
}
|
||||
|
||||
// Voxel
|
||||
xyz.ix = ix;
|
||||
xyz.iy = iy;
|
||||
xyz.iz = iz;
|
||||
|
||||
// Take the value
|
||||
const Standard_Byte value = ((iXYZBool*)mySubVoxels)->Find(xyz);
|
||||
|
||||
// Return data
|
||||
return (value & gbits[ioct]) ? Standard_True : Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_OctBoolDS::IsSplit(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
if (!mySubVoxels)
|
||||
return Standard_False;
|
||||
|
||||
// Voxel
|
||||
xyz.ix = ix;
|
||||
xyz.iy = iy;
|
||||
xyz.iz = iz;
|
||||
|
||||
return ((iXYZBool*)mySubVoxels)->IsBound(xyz);
|
||||
}
|
||||
|
||||
void Voxel_OctBoolDS::Split(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz)
|
||||
{
|
||||
// Voxel
|
||||
xyz.ix = ix;
|
||||
xyz.iy = iy;
|
||||
xyz.iz = iz;
|
||||
|
||||
if (mySubVoxels)
|
||||
{
|
||||
if (!((iXYZBool*)mySubVoxels)->IsBound(xyz))
|
||||
{
|
||||
((iXYZBool*)mySubVoxels)->Bind(xyz, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mySubVoxels = (Standard_Address) new iXYZBool;
|
||||
((iXYZBool*)mySubVoxels)->Bind(xyz, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_OctBoolDS::UnSplit(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz)
|
||||
{
|
||||
if (!mySubVoxels)
|
||||
return;
|
||||
|
||||
// Voxel
|
||||
xyz.ix = ix;
|
||||
xyz.iy = iy;
|
||||
xyz.iz = iz;
|
||||
|
||||
if (((iXYZBool*)mySubVoxels)->IsBound(xyz))
|
||||
{
|
||||
((iXYZBool*)mySubVoxels)->UnBind(xyz);
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_OctBoolDS::OptimizeMemory()
|
||||
{
|
||||
if (!mySubVoxels)
|
||||
return;
|
||||
|
||||
Standard_Byte value;
|
||||
iXYZBool::Iterator itr(*((iXYZBool*)mySubVoxels));
|
||||
for (; itr.More(); itr.Next())
|
||||
{
|
||||
value = itr.Value();
|
||||
if (value == 0 || value == 255)
|
||||
{
|
||||
xyz = itr.Key();
|
||||
Set(xyz.ix, xyz.iy, xyz.iz, value ? Standard_True : Standard_False);
|
||||
UnSplit(xyz.ix, xyz.iy, xyz.iz);
|
||||
}
|
||||
}
|
||||
|
||||
// If the map is empty, release it.
|
||||
if (((iXYZBool*)mySubVoxels)->IsEmpty())
|
||||
{
|
||||
delete (iXYZBool*)mySubVoxels;
|
||||
mySubVoxels = 0;
|
||||
}
|
||||
}
|
152
src/Voxel/Voxel_Prs.cdl
Executable file
152
src/Voxel/Voxel_Prs.cdl
Executable file
@@ -0,0 +1,152 @@
|
||||
-- File: Voxel_Prs.cdl
|
||||
-- Created: Tue May 06 15:41:47 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class Prs from Voxel inherits InteractiveObject from AIS
|
||||
|
||||
---Purpose: Interactive object for voxels.
|
||||
|
||||
uses
|
||||
|
||||
Presentation from Prs3d,
|
||||
PresentationManager3d from PrsMgr,
|
||||
Selection from SelectMgr,
|
||||
Color from Quantity,
|
||||
HArray1OfColor from Quantity,
|
||||
HArray1OfReal from TColStd,
|
||||
VoxelDisplayMode from Voxel,
|
||||
Triangulation from Poly
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns mutable Prs from Voxel;
|
||||
|
||||
|
||||
---Category: Set Voxels
|
||||
-- ==========
|
||||
|
||||
SetBoolVoxels(me : mutable;
|
||||
theVoxels : Address from Standard);
|
||||
---Purpose: <theVoxels> is a Voxel_BoolDS* object.
|
||||
|
||||
SetColorVoxels(me : mutable;
|
||||
theVoxels : Address from Standard);
|
||||
---Purpose: <theVoxels> is a Voxel_ColorDS* object.
|
||||
|
||||
SetROctBoolVoxels(me : mutable;
|
||||
theVoxels : Address from Standard);
|
||||
---Purpose: <theVoxels> is a Voxel_ROctBoolDS* object.
|
||||
|
||||
SetTriangulation(me : mutable;
|
||||
theTriangulation : Triangulation from Poly);
|
||||
---Purpose: Sets a triangulation for visualization.
|
||||
|
||||
|
||||
---Category: Visual attributes
|
||||
-- =================
|
||||
|
||||
SetDisplayMode(me : mutable;
|
||||
theMode : VoxelDisplayMode from Voxel);
|
||||
---Purpose: Sets a display mode for voxels.
|
||||
|
||||
SetColor(me : mutable;
|
||||
theColor : Color from Quantity)
|
||||
---Purpose: Defines the color of points, quadrangles ... for BoolDS.
|
||||
is redefined;
|
||||
|
||||
SetColors(me : mutable;
|
||||
theColors : HArray1OfColor from Quantity);
|
||||
---Purpose: Defines the color of points, quadrangles... for ColorDS.
|
||||
-- For ColorDS the size of array is 0 .. 15.
|
||||
-- 0 - means no color, this voxel is not drawn.
|
||||
|
||||
SetPointSize(me : mutable;
|
||||
theSize : Real from Standard);
|
||||
---Purpose: Defines the size of points for all types of voxels.
|
||||
|
||||
SetQuadrangleSize(me : mutable;
|
||||
theSize : Integer from Standard);
|
||||
---Purpose: Defines the size of quadrangles in per cents (0 .. 100).
|
||||
|
||||
SetTransparency(me : mutable;
|
||||
theTransparency : Real from Standard)
|
||||
---Purpose: Defines the transparency value [0 .. 1] for quadrangular visualization.
|
||||
is redefined;
|
||||
|
||||
Highlight(me : mutable;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard);
|
||||
---Purpose: Highlights a voxel.
|
||||
-- It doesn't re-computes the whole interactive object,
|
||||
-- but only marks a voxels as "highlighted".
|
||||
-- The voxel becomes highlighted on next swapping of buffers.
|
||||
-- In order to unhighlight a voxel, set ix = iy = iz = -1.
|
||||
|
||||
|
||||
---Category: Compute
|
||||
-- =======
|
||||
|
||||
Compute(me : mutable;
|
||||
thePresentationManager : PresentationManager3d from PrsMgr;
|
||||
thePresentation : mutable Presentation from Prs3d;
|
||||
theMode : Integer from Standard = 0)
|
||||
is redefined
|
||||
protected;
|
||||
|
||||
ComputeSelection(me : mutable;
|
||||
theSelection : mutable Selection from SelectMgr;
|
||||
theMode : Integer from Standard)
|
||||
is private;
|
||||
|
||||
Allocate(me : mutable)
|
||||
---Purpose: Allocates the data structure of visualization.
|
||||
is private;
|
||||
|
||||
Destroy(me : mutable);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of presentation data.
|
||||
|
||||
SetDegenerateMode(me : mutable;
|
||||
theDegenerate : Boolean from Standard);
|
||||
---Purpose: Simplifies visualization of voxels in case of view rotation, panning and zooming.
|
||||
|
||||
SetUsageOfGLlists(me : mutable;
|
||||
theUsage : Boolean from Standard);
|
||||
---Purpose: GL lists accelerate view rotation, panning and zooming operations, but
|
||||
-- it takes additional memory...
|
||||
-- It is up to the user of this interactive object to decide whether
|
||||
-- he has enough memory and may use GL lists or
|
||||
-- he is lack of memory and usage of GL lists is not recommended.
|
||||
-- By default, usage of GL lists is on.
|
||||
-- Also, as I noticed, the view without GL lists looks more precisely.
|
||||
|
||||
SetSmoothPoints(me : mutable;
|
||||
theSmooth : Boolean from Standard);
|
||||
---Purpose: Switches visualization of points from smooth to rough.
|
||||
|
||||
SetColorRange(me : mutable;
|
||||
theMinValue : Byte from Standard;
|
||||
theMaxValue : Byte from Standard);
|
||||
---Purpose: Defines min-max values for visualization of voxels of ColorDS structure.
|
||||
-- By default, min value = 1, max value = 15 (all non-zero values).
|
||||
|
||||
SetSizeRange(me : mutable;
|
||||
theDisplayedXMin : Real from Standard;
|
||||
theDisplayedXMax : Real from Standard;
|
||||
theDisplayedYMin : Real from Standard;
|
||||
theDisplayedYMax : Real from Standard;
|
||||
theDisplayedZMin : Real from Standard;
|
||||
theDisplayedZMax : Real from Standard);
|
||||
---Purpose: Defines the displayed area of voxels.
|
||||
-- By default, the range is equal to the box of voxels (all voxels are displayed).
|
||||
|
||||
fields
|
||||
|
||||
myVisData : Address from Standard;
|
||||
|
||||
end Prs;
|
292
src/Voxel/Voxel_Prs.cxx
Executable file
292
src/Voxel/Voxel_Prs.cxx
Executable file
@@ -0,0 +1,292 @@
|
||||
// File: Voxel_Prs.cxx
|
||||
// Created: Mon May 13 12:35:52 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_Prs.ixx>
|
||||
#include "Voxel_VisData.h"
|
||||
|
||||
#include <Prs3d_Root.hxx>
|
||||
#include <Graphic3d_Group.hxx>
|
||||
#include <Graphic3d_MaterialAspect.hxx>
|
||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||
|
||||
Voxel_Prs::Voxel_Prs():AIS_InteractiveObject(PrsMgr_TOP_AllView),myVisData(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetBoolVoxels(const Standard_Address theVoxels)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myBoolVoxels = (Voxel_BoolDS*) theVoxels;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetColorVoxels(const Standard_Address theVoxels)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myColorVoxels = (Voxel_ColorDS*) theVoxels;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetROctBoolVoxels(const Standard_Address theVoxels)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myROctBoolVoxels = (Voxel_ROctBoolDS*) theVoxels;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetTriangulation(const Handle(Poly_Triangulation)& theTriangulation)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myTriangulation = theTriangulation;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetColor(const Quantity_Color& theColor)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColor = theColor;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetPointSize(const Standard_Real theSize)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myPointSize = theSize;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetQuadrangleSize(const Standard_Integer theSize)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myQuadrangleSize = theSize;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetColors(const Handle(Quantity_HArray1OfColor)& theColors)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColors = theColors;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetDisplayMode(const Voxel_VoxelDisplayMode theMode)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayMode = theMode;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetTransparency(const Standard_Real theTransparency)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myTransparency = theTransparency;
|
||||
}
|
||||
|
||||
static void setMaterial(const Handle(Graphic3d_Group)& G,
|
||||
const Quantity_Color& C,
|
||||
const Standard_Real T)
|
||||
{
|
||||
Graphic3d_MaterialAspect material(Graphic3d_NOM_PLASTIC);
|
||||
material.SetColor(C);
|
||||
material.SetTransparency(T);
|
||||
Handle(Graphic3d_AspectFillArea3d) aspect =
|
||||
new Graphic3d_AspectFillArea3d(Aspect_IS_SOLID, C, C, Aspect_TOL_SOLID, 1, material, material);
|
||||
aspect->SetDistinguishOff();
|
||||
aspect->SetEdgeOff();
|
||||
aspect->SetTextureMapOff();
|
||||
G->SetPrimitivesAspect(aspect);
|
||||
}
|
||||
|
||||
void Voxel_Prs::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
|
||||
const Handle(Prs3d_Presentation)& thePresentation,
|
||||
const Standard_Integer /*theMode*/)
|
||||
{
|
||||
thePresentation->Clear();
|
||||
if (!myVisData)
|
||||
return;
|
||||
|
||||
if (((Voxel_VisData*)myVisData)->myBoolVoxels)
|
||||
{
|
||||
// Reset GL lists.
|
||||
// BoolDS
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsFirst = 1;
|
||||
}
|
||||
|
||||
if (((Voxel_VisData*)myVisData)->myColorVoxels)
|
||||
{
|
||||
// Reset GL lists.
|
||||
// ColorDS
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsFirst = 1;
|
||||
}
|
||||
|
||||
if (((Voxel_VisData*)myVisData)->myROctBoolVoxels)
|
||||
{
|
||||
// Reset GL lists.
|
||||
// ROctBoolDS
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsFirst = 1;
|
||||
}
|
||||
|
||||
// Set data to the user draw function.
|
||||
Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(thePresentation);
|
||||
if (((Voxel_VisData*)myVisData)->myDisplay.myDisplayMode == Voxel_VDM_BOXES ||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayMode == Voxel_VDM_NEARESTBOXES ||
|
||||
!((Voxel_VisData*)myVisData)->myTriangulation.IsNull())
|
||||
{
|
||||
setMaterial(G, ((Voxel_VisData*)myVisData)->myDisplay.myColor,
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myTransparency);
|
||||
|
||||
// Reset normals of triangulation
|
||||
if (!((Voxel_VisData*)myVisData)->myTriangulation.IsNull())
|
||||
{
|
||||
((Voxel_VisData*)myVisData)->myNormalsOfNodes.Nullify();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myTriangulationList = -1;
|
||||
}
|
||||
}
|
||||
|
||||
G->UserDraw(myVisData);
|
||||
}
|
||||
|
||||
void Voxel_Prs::ComputeSelection(const Handle(SelectMgr_Selection)& /*theSelection*/,
|
||||
const Standard_Integer /*theMode*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_Prs::Destroy()
|
||||
{
|
||||
if (myVisData)
|
||||
{
|
||||
delete (Voxel_VisData*) myVisData;
|
||||
myVisData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_Prs::Allocate()
|
||||
{
|
||||
if (!myVisData)
|
||||
{
|
||||
myVisData = new Voxel_VisData;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myBoolVoxels = 0;
|
||||
((Voxel_VisData*)myVisData)->myColorVoxels = 0;
|
||||
((Voxel_VisData*)myVisData)->myROctBoolVoxels = 0;
|
||||
|
||||
// Points
|
||||
|
||||
// BoolDS
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolPointsList = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[0] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[1] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[2] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[3] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[4] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[5] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsList[6] = -1;
|
||||
|
||||
// ROctBoolDS
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolPointsList = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[0] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[1] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[2] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[3] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[4] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[5] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsList[6] = -1;
|
||||
|
||||
// ColorDS:
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorPointsList = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[0] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[1] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[2] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[3] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[4] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[5] = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsList[6] = -1;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorMinValue = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorMaxValue = 15;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myPointSize = 1.0;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myQuadrangleSize = 100;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myTransparency = 0.0;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDegenerateMode = 0;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myUsageOfGLlists = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.mySmoothPoints = 0;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedXMin = -DBL_MAX;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedXMax = DBL_MAX;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedYMin = -DBL_MAX;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedYMax = DBL_MAX;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedZMin = -DBL_MAX;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedZMax = DBL_MAX;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myTriangulationList = -1;
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlightx = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlighty = -1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlightz = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetDegenerateMode(const Standard_Boolean theDegenerate)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDegenerateMode = (theDegenerate == Standard_True);
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetUsageOfGLlists(const Standard_Boolean theUsage)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myUsageOfGLlists = (theUsage == Standard_True);
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetSmoothPoints(const Standard_Boolean theSmooth)
|
||||
{
|
||||
Allocate();
|
||||
((Voxel_VisData*)myVisData)->myDisplay.mySmoothPoints = (theSmooth == Standard_True);
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetColorRange(const Standard_Byte theMinValue,
|
||||
const Standard_Byte theMaxValue)
|
||||
{
|
||||
Allocate();
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorMinValue = theMinValue;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorMaxValue = theMaxValue;
|
||||
|
||||
// Reset GL lists
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsFirst = 1;
|
||||
}
|
||||
|
||||
void Voxel_Prs::SetSizeRange(const Standard_Real theDisplayedXMin,
|
||||
const Standard_Real theDisplayedXMax,
|
||||
const Standard_Real theDisplayedYMin,
|
||||
const Standard_Real theDisplayedYMax,
|
||||
const Standard_Real theDisplayedZMin,
|
||||
const Standard_Real theDisplayedZMax)
|
||||
{
|
||||
Allocate();
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedXMin = theDisplayedXMin;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedXMax = theDisplayedXMax;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedYMin = theDisplayedYMin;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedYMax = theDisplayedYMax;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedZMin = theDisplayedZMin;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myDisplayedZMax = theDisplayedZMax;
|
||||
|
||||
// Reset GL lists
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myBoolNearestPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myColorNearestPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolPointsFirst = 1;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myROctBoolNearestPointsFirst = 1;
|
||||
}
|
||||
|
||||
void Voxel_Prs::Highlight(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz)
|
||||
{
|
||||
Allocate();
|
||||
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlightx = ix;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlighty = iy;
|
||||
((Voxel_VisData*)myVisData)->myDisplay.myHighlightz = iz;
|
||||
}
|
177
src/Voxel/Voxel_ROctBoolDS.cdl
Executable file
177
src/Voxel/Voxel_ROctBoolDS.cdl
Executable file
@@ -0,0 +1,177 @@
|
||||
-- File: Voxel_ROctBoolDS.cdl
|
||||
-- Created: Sun Sep 01 10:36:25 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class ROctBoolDS from Voxel inherits DS from Voxel
|
||||
|
||||
---Purpose: A 3D voxel model keeping a boolean flag (1 or 0)
|
||||
-- value for each voxel, and having an opportunity to split each voxel
|
||||
-- into 8 sub-voxels recursively.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns ROctBoolDS from Voxel;
|
||||
|
||||
Create(x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: A constructor initializing the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
returns ROctBoolDS from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
x : Real from Standard;
|
||||
y : Real from Standard;
|
||||
z : Real from Standard;
|
||||
x_len : Real from Standard;
|
||||
y_len : Real from Standard;
|
||||
z_len : Real from Standard;
|
||||
nb_x : Integer from Standard;
|
||||
nb_y : Integer from Standard;
|
||||
nb_z : Integer from Standard)
|
||||
---Purpose: Initialization of the voxel model.
|
||||
-- (x, y, z) - the start point of the box.
|
||||
-- (x_len, y_len, z_len) - lengths in x, y and z directions along axes of a co-ordinate system.
|
||||
-- (nb_x, nb_y, nb_z) - number of splits (voxels) along x, y and z directions.
|
||||
is redefined virtual;
|
||||
|
||||
Destroy(me : in out);
|
||||
---C++: alias ~
|
||||
---Purpose: A destructor of the voxel model.
|
||||
|
||||
SetZero(me : in out);
|
||||
---Purpose: The method sets all values equal to 0 (false) and
|
||||
-- releases the memory.
|
||||
|
||||
OptimizeMemory(me : in out);
|
||||
---Purpose: The method searches voxels with equal-value of sub-voxels
|
||||
-- and removes them (remaining the value for the voxel).
|
||||
|
||||
|
||||
---Category: Set
|
||||
-- ===
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
data : Boolean from Standard);
|
||||
---Purpose: Defines a value for voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is split into 8 sub-voxels, the split disappears.
|
||||
-- Initial state of the model is so that all voxels have value 0 (false),
|
||||
-- and this data doesn't occupy memory.
|
||||
-- Memory for data is allocating during setting non-zero values (true).
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct1 : Integer from Standard;
|
||||
data : Boolean from Standard);
|
||||
---Purpose: Defines a value for a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split into 8 sub-voxels yet, this method splits the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
|
||||
Set(me : in out;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct1 : Integer from Standard;
|
||||
ioct2 : Integer from Standard;
|
||||
data : Boolean from Standard);
|
||||
---Purpose: Defines a value for a sub-voxel of a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split into 8 sub-voxels yet, this method splits the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
|
||||
|
||||
---Category: Get
|
||||
-- ===
|
||||
|
||||
IsSplit(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns true if the voxel is split into 8 sub-voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Deepness(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the deepness of splits of a voxel.
|
||||
-- 0 - no splits (::IsSplit() being called would return false).
|
||||
-- 1 - the voxel is split into 8 sub-voxels.
|
||||
-- 2 - the voxels is split into 8 sub-voxels,
|
||||
-- and each of the sub-voxels is split into 8 sub-sub-voxels.
|
||||
-- 3 - ...
|
||||
returns Integer from Standard;
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard)
|
||||
---Purpose: Returns the value of voxel with co-ordinates (ix, iy, iz).
|
||||
-- Warning!: the returned value may not coincide with the value of its 8 sub-voxels.
|
||||
-- Use the method ::IsSplit() to check whether a voxel has sub-voxels.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct1 : Integer from Standard)
|
||||
---Purpose: Returns the value of a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split, it returns the value of the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
returns Boolean from Standard;
|
||||
|
||||
Get(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
ioct1 : Integer from Standard;
|
||||
ioct2 : Integer from Standard)
|
||||
---Purpose: Returns the value of a sub-voxel of a sub-voxel of a voxel with co-ordinates (ix, iy, iz).
|
||||
-- If the voxel is not split, it returns the value of the voxel.
|
||||
-- Range of sub-voxels is 0 - 7.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Category: Services
|
||||
-- ========
|
||||
|
||||
GetCenter(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
i : Integer from Standard;
|
||||
xc : out Real from Standard;
|
||||
yc : out Real from Standard;
|
||||
zc : out Real from Standard);
|
||||
---Purpose: Returns the center point of a sub-voxel with co-ordinates (ix, iy, iz, i).
|
||||
|
||||
GetCenter(me;
|
||||
ix : Integer from Standard;
|
||||
iy : Integer from Standard;
|
||||
iz : Integer from Standard;
|
||||
i : Integer from Standard;
|
||||
j : Integer from Standard;
|
||||
xc : out Real from Standard;
|
||||
yc : out Real from Standard;
|
||||
zc : out Real from Standard);
|
||||
---Purpose: Returns the center point of a sub-voxel with co-ordinates (ix, iy, iz, i, j).
|
||||
|
||||
|
||||
end ROctBoolDS;
|
717
src/Voxel/Voxel_ROctBoolDS.cxx
Executable file
717
src/Voxel/Voxel_ROctBoolDS.cxx
Executable file
@@ -0,0 +1,717 @@
|
||||
// File: Voxel_ROctBoolDS.cxx
|
||||
// Created: Mon Sep 01 11:00:08 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_ROctBoolDS.ixx>
|
||||
#include <Voxel_SplitData.hxx>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static Standard_Byte gbits[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
||||
static Standard_Byte gnbits[8] = {255-1, 255-2, 255-4, 255-8, 255-16, 255-32, 255-64, 255-128};
|
||||
|
||||
/* Data structure of the ROctBoolDS
|
||||
|
||||
SplitData: 1 byte (8 values)
|
||||
(a) SplitData: 8 bytes (64 values)
|
||||
(b) SplitData: 64 bytes (512 values)
|
||||
(c) SplitData: ...
|
||||
(d) SplitData: ...
|
||||
*/
|
||||
|
||||
// Empty constructor
|
||||
Voxel_ROctBoolDS::Voxel_ROctBoolDS():Voxel_DS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Constructor with intialization.
|
||||
Voxel_ROctBoolDS::Voxel_ROctBoolDS(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
:Voxel_DS()
|
||||
{
|
||||
Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
void Voxel_ROctBoolDS::Init(const Standard_Real x, const Standard_Real y, const Standard_Real z,
|
||||
const Standard_Real xlen, const Standard_Real ylen, const Standard_Real zlen,
|
||||
const Standard_Integer nbx, const Standard_Integer nby, const Standard_Integer nbz)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Voxel_DS::Init(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
if (!myNbX || !myNbY || !myNbZ)
|
||||
return;
|
||||
|
||||
Standard_Integer nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
myData = (Standard_Address) calloc(nb_slices, sizeof(Voxel_SplitData*));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
void Voxel_ROctBoolDS::Destroy()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
SetZero();
|
||||
free((Voxel_SplitData**)myData);
|
||||
myData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// A recursive method of deletion of data.
|
||||
static void SetZeroSplitData(Voxel_SplitData* data)
|
||||
{
|
||||
// Values:
|
||||
free((Standard_Byte*) data->GetValues());
|
||||
data->GetValues() = 0;
|
||||
if (data->GetSplitData())
|
||||
{
|
||||
SetZeroSplitData((Voxel_SplitData*) data->GetSplitData());
|
||||
}
|
||||
delete (data);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::SetZero()
|
||||
{
|
||||
if (myData)
|
||||
{
|
||||
Standard_Integer ix = 0, nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
for (; ix < nb_slices; ix++)
|
||||
{
|
||||
if (((Voxel_SplitData**)myData)[ix])
|
||||
{
|
||||
SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData**)myData)[ix]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Access to the boolean information attached to a particular voxel:
|
||||
// Info: (ix >= 0 && ix < theNb_x), etc.
|
||||
void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Boolean data)
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
if (!data && !((Voxel_SplitData**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
{
|
||||
((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Values:
|
||||
((Voxel_SplitData**)myData)[islice]->GetValues() =
|
||||
(Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
|
||||
// Sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Value
|
||||
Standard_Byte value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit - (islice << 3);
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[shift]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[shift];
|
||||
else
|
||||
value &= gnbits[shift];
|
||||
*((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues()) = value;
|
||||
}
|
||||
|
||||
// Set the same value to sub-voxels.
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
{
|
||||
// Get sub-value
|
||||
Standard_Byte subvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift];
|
||||
|
||||
// Set sub-value
|
||||
if (subvalue != (data ? 255 : 0))
|
||||
{
|
||||
subvalue = data ? 255 : 0;
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = subvalue;
|
||||
}
|
||||
|
||||
// Set the same value to sub-sub-voxels.
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
{
|
||||
// Start index of 64-bit value (index of byte of sub-sub-voxel).
|
||||
Standard_Integer ibyte2 = (shift << 3);
|
||||
for (Standard_Integer ioct2 = 0; ioct2 < 8; ioct2++)
|
||||
{
|
||||
// Get sub-sub-value
|
||||
Standard_Byte subsubvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + ioct2];
|
||||
|
||||
// Set sub-sub-value
|
||||
if (subsubvalue != (data ? 255 : 0))
|
||||
{
|
||||
subsubvalue = data ? 255 : 0;
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + ioct2] = subsubvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct1, const Standard_Boolean data)
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
if (!data && !((Voxel_SplitData**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
{
|
||||
((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Values:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues() =
|
||||
(Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
|
||||
// Sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Check sub-voxels of the first level
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
{
|
||||
// Sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = (Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Value of sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues() =
|
||||
(Standard_Byte*) calloc(8/*eight bytes: 8 sub-voxels for each voxel*/, sizeof(Standard_Byte));
|
||||
|
||||
// Set parent value
|
||||
Standard_Byte parent_value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
|
||||
if (parent_value)
|
||||
{
|
||||
for (Standard_Integer shift = 0; shift < 8; shift++)
|
||||
{
|
||||
if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-sub-voxels
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
|
||||
Standard_Integer ibyte = ibit - (islice << 3);
|
||||
|
||||
// Value
|
||||
Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte];
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[ioct1]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[ioct1];
|
||||
else
|
||||
value &= gnbits[ioct1];
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte] = value;
|
||||
}
|
||||
|
||||
// Set the same value to sub-voxels.
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
{
|
||||
// Start index of 64-bit value (index of byte of sub-sub-voxel).
|
||||
Standard_Integer ibyte2 = (ibyte << 3) + ioct1;
|
||||
|
||||
// Get sub-sub-value
|
||||
Standard_Byte subsubvalue = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
|
||||
|
||||
// Set sub-sub-value
|
||||
if (subsubvalue != (data ? 255 : 0))
|
||||
{
|
||||
subsubvalue = data ? 255 : 0;
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2] = subsubvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::Set(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct1, const Standard_Integer ioct2, const Standard_Boolean data)
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
if (!data && !((Voxel_SplitData**)myData)[islice])
|
||||
return; // don't allocate a slice of data for setting a 0 value
|
||||
|
||||
// Allocate the slice if it is not done yet.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
{
|
||||
((Voxel_SplitData**)myData)[islice] = (Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Values:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues() =
|
||||
(Standard_Byte*) calloc(1/*one byte: 8 1-bit values*/, sizeof(Standard_Byte));
|
||||
// Sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Check sub-voxels of the first level
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
{
|
||||
// Sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = (Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Value of sub-voxels:
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues() =
|
||||
(Standard_Byte*) calloc(8/*eight bytes: 8 sub-voxels for each voxel*/, sizeof(Standard_Byte));
|
||||
|
||||
// Set parent value
|
||||
Standard_Byte parent_value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
|
||||
if (parent_value)
|
||||
{
|
||||
for (Standard_Integer shift = 0; shift < 8; shift++)
|
||||
{
|
||||
if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[shift] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-sub-voxels
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Check sub-voxels of the second level
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
{
|
||||
// Sub-voxels 2:
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() =
|
||||
(Voxel_SplitData*) new Voxel_SplitData;
|
||||
// Value of sub-voxels 2:
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues() =
|
||||
(Standard_Byte*) calloc(64/*sixty four bytes: 8 sub-voxels for each sub-voxel for each voxel*/,
|
||||
sizeof(Standard_Byte));
|
||||
|
||||
// Set parent value
|
||||
for (Standard_Integer ibyte1 = 0; ibyte1 < 8; ibyte1++)
|
||||
{
|
||||
Standard_Byte parent_value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1];
|
||||
if (parent_value)
|
||||
{
|
||||
Standard_Integer ibyte2 = (ibyte1 << 3);
|
||||
for (Standard_Integer shift = 0; shift < 8; shift++)
|
||||
{
|
||||
if ((parent_value & gbits[shift]) ? Standard_True : Standard_False)
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + shift] = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2 + shift] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-sub-sub-voxels
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetSplitData() = 0;
|
||||
}
|
||||
|
||||
// Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
|
||||
Standard_Integer ibyte1 = ibit - (islice << 3); // imdex of byte of 8-byte value (sub-voxel 1).
|
||||
Standard_Integer ibyte2 = (ibyte1 << 3) + ioct1; // index of byte of 64-byte value (sub-voxel 2)
|
||||
|
||||
// Value
|
||||
Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
|
||||
|
||||
// Set data
|
||||
if (data != ((value & gbits[ioct2]) ? Standard_True : Standard_False))
|
||||
{
|
||||
if (data)
|
||||
value |= gbits[ioct2];
|
||||
else
|
||||
value &= gnbits[ioct2];
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// Value (byte)
|
||||
Standard_Byte value = *((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues());
|
||||
|
||||
// Position of data in the 8 bit-"value".
|
||||
Standard_Integer shift = ibit - (islice << 3);
|
||||
return ((value & gbits[shift]) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct1) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// If the voxel is not split, return the value of the voxel.
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
return Get(ix, iy, iz);
|
||||
|
||||
// Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
|
||||
Standard_Integer ibyte = ibit - (islice << 3);
|
||||
|
||||
// Value
|
||||
Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte];
|
||||
|
||||
return ((value & gbits[ioct1]) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_ROctBoolDS::Get(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer ioct1, const Standard_Integer ioct2) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
// If the slice of data is not allocated, it means that its values are 0.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// If the voxel is not split, return the value of the voxel.
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
return Get(ix, iy, iz);
|
||||
|
||||
// If the split voxel (sub-voxel 1) is not split, return the value of the sub-voxel 1.
|
||||
if (!((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
return Get(ix, iy, iz, ioct1);
|
||||
|
||||
// Index of sub-voxel corresponding to ioct1: 8 voxels correspond to 64 sub-voxels.
|
||||
Standard_Integer ibyte1 = ibit - (islice << 3); // index of byte of 8-byte value (sub-voxel 1).
|
||||
Standard_Integer ibyte2 = (ibyte1 << 3) + ioct1; // index of byte of 64-byte value (sub-voxel 2)
|
||||
|
||||
// Value
|
||||
Standard_Byte value = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
|
||||
|
||||
return ((value & gbits[ioct2]) ? Standard_True : Standard_False);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_ROctBoolDS::IsSplit(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
// If the voxel has no value, it is not split.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
return Standard_False;
|
||||
|
||||
// Check existence of sub-voxels
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
return Standard_True;
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Integer Voxel_ROctBoolDS::Deepness(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz) const
|
||||
{
|
||||
Standard_Integer ibit = ix + myNbX * iy + myNbXY * iz;
|
||||
Standard_Integer islice = ibit >> 3;
|
||||
|
||||
// If the voxel has no value, it is not split.
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
return 0;
|
||||
|
||||
// Test deepness.
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
{
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::OptimizeMemory()
|
||||
{
|
||||
// Iterate the array of voxels checking coincidence of values of sub-voxels.
|
||||
Standard_Integer islice = 0, nb_slices = RealToInt(ceil(myNbXY * myNbZ / 8.0));
|
||||
for (; islice < nb_slices; islice++)
|
||||
{
|
||||
if (!((Voxel_SplitData**)myData)[islice])
|
||||
continue;
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())
|
||||
{
|
||||
Standard_Boolean suppress = Standard_False;
|
||||
// Second level of sub-voxels
|
||||
if (((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())
|
||||
{
|
||||
suppress = Standard_False;
|
||||
Standard_Byte value1 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[0];
|
||||
if (value1 == 0 || value1 == 255)
|
||||
{
|
||||
suppress = Standard_True;
|
||||
for (Standard_Integer ibyte2 = 1; ibyte2 < 64; ibyte2++)
|
||||
{
|
||||
Standard_Byte value2 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData())->GetValues())[ibyte2];
|
||||
if (value2 != value1)
|
||||
{
|
||||
suppress = Standard_False;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (suppress)
|
||||
{
|
||||
SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData());
|
||||
((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetSplitData() = 0;
|
||||
// Set value to upper level
|
||||
for (Standard_Integer ibyte1 = 0; ibyte1 < 8; ibyte1++)
|
||||
{
|
||||
((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1] = value1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't suppress sub-sub-voxels, we don't touch sub-voxels.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// First level of sub-voxels
|
||||
suppress = Standard_False;
|
||||
Standard_Byte value1 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[0];
|
||||
if (value1 == 0 || value1 == 255)
|
||||
{
|
||||
suppress = Standard_True;
|
||||
for (Standard_Integer ibyte1 = 1; ibyte1 < 8; ibyte1++)
|
||||
{
|
||||
Standard_Byte value2 = ((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData())->GetValues())[ibyte1];
|
||||
if (value2 != value1)
|
||||
{
|
||||
suppress = Standard_False;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (suppress)
|
||||
{
|
||||
SetZeroSplitData((Voxel_SplitData*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData());
|
||||
((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetSplitData() = 0;
|
||||
// Set value to upper level
|
||||
*((Standard_Byte*)((Voxel_SplitData*)((Voxel_SplitData**)myData)[islice])->GetValues()) = value1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::GetCenter(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer i,
|
||||
Standard_Real& xc, Standard_Real& yc, Standard_Real& zc) const
|
||||
{
|
||||
xc = myX + ix * myDX;
|
||||
yc = myY + iy * myDY;
|
||||
zc = myZ + iz * myDZ;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
xc += 0.5 * myHalfDX;
|
||||
yc += 0.5 * myHalfDY;
|
||||
zc += 0.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
xc += 1.5 * myHalfDX;
|
||||
yc += 0.5 * myHalfDY;
|
||||
zc += 0.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
xc += 0.5 * myHalfDX;
|
||||
yc += 1.5 * myHalfDY;
|
||||
zc += 0.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
xc += 1.5 * myHalfDX;
|
||||
yc += 1.5 * myHalfDY;
|
||||
zc += 0.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
xc += 0.5 * myHalfDX;
|
||||
yc += 0.5 * myHalfDY;
|
||||
zc += 1.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
xc += 1.5 * myHalfDX;
|
||||
yc += 0.5 * myHalfDY;
|
||||
zc += 1.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
xc += 0.5 * myHalfDX;
|
||||
yc += 1.5 * myHalfDY;
|
||||
zc += 1.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
xc += 1.5 * myHalfDX;
|
||||
yc += 1.5 * myHalfDY;
|
||||
zc += 1.5 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Voxel_ROctBoolDS::GetCenter(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer i, const Standard_Integer j,
|
||||
Standard_Real& xc, Standard_Real& yc, Standard_Real& zc) const
|
||||
{
|
||||
xc = myX + ix * myDX;
|
||||
yc = myY + iy * myDY;
|
||||
zc = myZ + iz * myDZ;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
xc += myHalfDX;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
yc += myHalfDY;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
xc += myHalfDX;
|
||||
yc += myHalfDY;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
zc += myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
xc += myHalfDX;
|
||||
zc += myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
yc += myHalfDY;
|
||||
zc += myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
xc += myHalfDX;
|
||||
yc += myHalfDY;
|
||||
zc += myHalfDZ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
xc += 0.25 * myHalfDX;
|
||||
yc += 0.25 * myHalfDY;
|
||||
zc += 0.25 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
xc += 0.75 * myHalfDX;
|
||||
yc += 0.25 * myHalfDY;
|
||||
zc += 0.25 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
xc += 0.25 * myHalfDX;
|
||||
yc += 0.75 * myHalfDY;
|
||||
zc += 0.25 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
xc += 0.75 * myHalfDX;
|
||||
yc += 0.75 * myHalfDY;
|
||||
zc += 0.25 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
xc += 0.25 * myHalfDX;
|
||||
yc += 0.25 * myHalfDY;
|
||||
zc += 0.75 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
xc += 0.75 * myHalfDX;
|
||||
yc += 0.25 * myHalfDY;
|
||||
zc += 0.75 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
xc += 0.25 * myHalfDX;
|
||||
yc += 0.75 * myHalfDY;
|
||||
zc += 0.75 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
xc += 0.75 * myHalfDX;
|
||||
yc += 0.75 * myHalfDY;
|
||||
zc += 0.75 * myHalfDZ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
101
src/Voxel/Voxel_Reader.cdl
Executable file
101
src/Voxel/Voxel_Reader.cdl
Executable file
@@ -0,0 +1,101 @@
|
||||
-- File: Voxel_Reader.cdl
|
||||
-- Created: Wed Aug 28 17:23:34 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class Reader from Voxel
|
||||
|
||||
---Purpose: Reads a cube of voxels from disk.
|
||||
-- Beware, a caller of the reader is responsible for deletion of the read voxels.
|
||||
|
||||
uses
|
||||
|
||||
BoolDS from Voxel,
|
||||
ColorDS from Voxel,
|
||||
FloatDS from Voxel,
|
||||
ExtendedString from TCollection
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns Reader from Voxel;
|
||||
|
||||
Read(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads the voxels from disk
|
||||
returns Boolean from Standard;
|
||||
|
||||
IsBoolVoxels(me)
|
||||
---Purpose: Informs the user about the type of voxels he has read.
|
||||
returns Boolean from Standard;
|
||||
|
||||
IsColorVoxels(me)
|
||||
---Purpose: Informs the user about the type of voxels he has read.
|
||||
returns Boolean from Standard;
|
||||
|
||||
IsFloatVoxels(me)
|
||||
---Purpose: Informs the user about the type of voxels he has read.
|
||||
returns Boolean from Standard;
|
||||
|
||||
GetBoolVoxels(me)
|
||||
---Purpose: Returns a pointer to the read 1bit voxels.
|
||||
returns Address from Standard;
|
||||
|
||||
GetColorVoxels(me)
|
||||
---Purpose: Returns a pointer to the read 4bit voxels.
|
||||
returns Address from Standard;
|
||||
|
||||
GetFloatVoxels(me)
|
||||
---Purpose: Returns a pointer to the read 4bytes voxels.
|
||||
returns Address from Standard;
|
||||
|
||||
|
||||
---Private area
|
||||
-- ============
|
||||
|
||||
ReadBoolAsciiVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 1bit voxels from disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
ReadColorAsciiVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 4bit voxels from disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
ReadFloatAsciiVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 4bytes voxels from disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
ReadBoolBinaryVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 1bit voxels from disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
ReadColorBinaryVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 4bit voxels from disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
ReadFloatBinaryVoxels(me : in out;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Reads 4bytes voxels from disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myBoolVoxels : Address from Standard;
|
||||
myColorVoxels : Address from Standard;
|
||||
myFloatVoxels : Address from Standard;
|
||||
|
||||
end Reader;
|
527
src/Voxel/Voxel_Reader.cxx
Executable file
527
src/Voxel/Voxel_Reader.cxx
Executable file
@@ -0,0 +1,527 @@
|
||||
// File: Voxel_Reader.cxx
|
||||
// Created: Wed Aug 28 19:34:33 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_Reader.ixx>
|
||||
#include <Voxel_BoolDS.hxx>
|
||||
#include <Voxel_ColorDS.hxx>
|
||||
#include <Voxel_FloatDS.hxx>
|
||||
#include <Voxel_VoxelFileFormat.hxx>
|
||||
#include <Voxel_TypeDef.hxx>
|
||||
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
Voxel_Reader::Voxel_Reader():myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::Read(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file in ASCII mode to read header
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Read the header
|
||||
Standard_Byte type; // 0 - bool, 1 - color, 2 - float
|
||||
Voxel_VoxelFileFormat format;
|
||||
Standard_Character svoxels[8], sformat[8], stype[8];
|
||||
fscanf(f, "%s %s %s\n", svoxels, sformat, stype);
|
||||
fclose(f);
|
||||
|
||||
// Take format, type of voxels.
|
||||
// Voxels
|
||||
if (strcmp(svoxels, VOXELS))
|
||||
return Standard_False;
|
||||
// Format
|
||||
if (strcmp(sformat, ASCII) == 0)
|
||||
format = Voxel_VFF_ASCII;
|
||||
else if (strcmp(sformat, BINARY) == 0)
|
||||
format = Voxel_VFF_BINARY;
|
||||
else
|
||||
return Standard_False;
|
||||
// Type of voxels
|
||||
if (strcmp(stype, BOOL) == 0)
|
||||
type = 0;
|
||||
else if (strcmp(stype, COLOR) == 0)
|
||||
type = 1;
|
||||
else if (strcmp(stype, FLOAT) == 0)
|
||||
type = 2;
|
||||
else
|
||||
return Standard_False;
|
||||
|
||||
// Read the rest
|
||||
switch (format)
|
||||
{
|
||||
case Voxel_VFF_ASCII:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return ReadBoolAsciiVoxels(file);
|
||||
case 1:
|
||||
return ReadColorAsciiVoxels(file);
|
||||
case 2:
|
||||
return ReadFloatAsciiVoxels(file);
|
||||
}
|
||||
}
|
||||
case Voxel_VFF_BINARY:
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return ReadBoolBinaryVoxels(file);
|
||||
case 1:
|
||||
return ReadColorBinaryVoxels(file);
|
||||
case 2:
|
||||
return ReadFloatBinaryVoxels(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No voxels or no format description is found:
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::IsBoolVoxels() const
|
||||
{
|
||||
return (myBoolVoxels != 0);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::IsColorVoxels() const
|
||||
{
|
||||
return (myColorVoxels != 0);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::IsFloatVoxels() const
|
||||
{
|
||||
return (myFloatVoxels != 0);
|
||||
}
|
||||
|
||||
Standard_Address Voxel_Reader::GetBoolVoxels() const
|
||||
{
|
||||
return myBoolVoxels;
|
||||
}
|
||||
|
||||
Standard_Address Voxel_Reader::GetColorVoxels() const
|
||||
{
|
||||
return myColorVoxels;
|
||||
}
|
||||
|
||||
Standard_Address Voxel_Reader::GetFloatVoxels() const
|
||||
{
|
||||
return myFloatVoxels;
|
||||
}
|
||||
|
||||
static Standard_Boolean has_slice(const Standard_CString line)
|
||||
{
|
||||
Standard_Integer i = 0, nb_spaces = 0;
|
||||
while (line[i] != '\0')
|
||||
{
|
||||
if (line[i] == ' ')
|
||||
nb_spaces++;
|
||||
i++;
|
||||
}
|
||||
return (nb_spaces == 2);
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadBoolAsciiVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
Standard_Character line[64], sx[32], sy[32], sz[32];
|
||||
|
||||
// Header: skip it
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
x = atof(sx); y = atof(sy); z = atof(sz);
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
xlen = atof(sx); ylen = atof(sy); zlen = atof(sz);
|
||||
if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Allocate the voxels
|
||||
myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_BoolDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 7]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0, value = 0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fgets(line, 64, f);
|
||||
if (has_slice(line))
|
||||
{
|
||||
if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sscanf(line, "%d %d\n", &i2, &value) != 2)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Set value
|
||||
if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] =
|
||||
(Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
(((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadColorAsciiVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
Standard_Character line[64], sx[32], sy[32], sz[32];
|
||||
|
||||
// Header: skip it
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
x = atof(sx); y = atof(sy); z = atof(sz);
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
xlen = atof(sx); ylen = atof(sy); zlen = atof(sz);
|
||||
if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Allocate the voxels
|
||||
myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_ColorDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0, value = 0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fgets(line, 64, f);
|
||||
if (has_slice(line))
|
||||
{
|
||||
if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sscanf(line, "%d %d\n", &i2, &value) != 2)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Set value
|
||||
if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] =
|
||||
(Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
(((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadFloatAsciiVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "r");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
Standard_Character line[64], sx[32], sy[32], sz[32];
|
||||
|
||||
// Header: skip it
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
x = atof(sx); y = atof(sy); z = atof(sz);
|
||||
if (fscanf(f, "%s %s %s\n", sx, sy, sz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
xlen = atof(sx); ylen = atof(sy); zlen = atof(sz);
|
||||
if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Allocate the voxels
|
||||
myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_FloatDS.cxx:
|
||||
Standard_Integer nb_floats = nbx * nby * nbz;
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
Standard_ShortReal value = 0.0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fgets(line, 64, f);
|
||||
if (has_slice(line))
|
||||
{
|
||||
if (sscanf(line, "%d %d %s\n", &i1, &i2, line) != 3)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sscanf(line, "%d %s\n", &i2, line) != 2)
|
||||
{
|
||||
fclose(f);
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
value = atof(line);
|
||||
|
||||
// Set value
|
||||
if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] =
|
||||
(Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
|
||||
}
|
||||
(((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadBoolBinaryVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: skip it
|
||||
Standard_Character line[64];
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
fread(&x, sizeof(Standard_Real), 1, f);
|
||||
fread(&y, sizeof(Standard_Real), 1, f);
|
||||
fread(&z, sizeof(Standard_Real), 1, f);
|
||||
fread(&xlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&ylen, sizeof(Standard_Real), 1, f);
|
||||
fread(&zlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&nbx, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nby, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nbz, sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Allocate the voxels
|
||||
myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_BoolDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 7]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0, value = 0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fread(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fread(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fread(&value, sizeof(Standard_Byte), 1, f);
|
||||
|
||||
// Set value
|
||||
if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] =
|
||||
(Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
(((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadColorBinaryVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: skip it
|
||||
Standard_Character line[64];
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
fread(&x, sizeof(Standard_Real), 1, f);
|
||||
fread(&y, sizeof(Standard_Real), 1, f);
|
||||
fread(&z, sizeof(Standard_Real), 1, f);
|
||||
fread(&xlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&ylen, sizeof(Standard_Real), 1, f);
|
||||
fread(&zlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&nbx, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nby, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nbz, sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Allocate the voxels
|
||||
myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_ColorDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0, value = 0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fread(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fread(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fread(&value, sizeof(Standard_Byte), 1, f);
|
||||
|
||||
// Set value
|
||||
if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] =
|
||||
(Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
|
||||
}
|
||||
(((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Reader::ReadFloatBinaryVoxels(const TCollection_ExtendedString& file)
|
||||
{
|
||||
// Open file for reading
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "rb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: skip it
|
||||
Standard_Character line[64];
|
||||
fgets(line, 64, f);
|
||||
|
||||
// Location, size, number of splits
|
||||
Standard_Integer nbx = 0, nby = 0, nbz = 0;
|
||||
Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
|
||||
fread(&x, sizeof(Standard_Real), 1, f);
|
||||
fread(&y, sizeof(Standard_Real), 1, f);
|
||||
fread(&z, sizeof(Standard_Real), 1, f);
|
||||
fread(&xlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&ylen, sizeof(Standard_Real), 1, f);
|
||||
fread(&zlen, sizeof(Standard_Real), 1, f);
|
||||
fread(&nbx, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nby, sizeof(Standard_Integer), 1, f);
|
||||
fread(&nbz, sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Allocate the voxels
|
||||
myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_FloatDS.cxx:
|
||||
Standard_Integer nb_floats = nbx * nby * nbz;
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
Standard_ShortReal value = 0.0;
|
||||
while (!feof(f))
|
||||
{
|
||||
fread(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fread(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fread(&value, sizeof(Standard_ShortReal), 1, f);
|
||||
|
||||
// Set value
|
||||
if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
|
||||
{
|
||||
((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] =
|
||||
(Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
|
||||
}
|
||||
(((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
62
src/Voxel/Voxel_Selector.cdl
Executable file
62
src/Voxel/Voxel_Selector.cdl
Executable file
@@ -0,0 +1,62 @@
|
||||
-- File: Voxel_Selector.cdl
|
||||
-- Created: Wed Jul 30 15:36:49 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class Selector from Voxel
|
||||
|
||||
---Purpose: Detects voxels in the viewer 3d under the mouse cursor.
|
||||
|
||||
uses
|
||||
|
||||
View from V3d,
|
||||
BoolDS from Voxel,
|
||||
ColorDS from Voxel,
|
||||
ROctBoolDS from Voxel
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns Selector from Voxel;
|
||||
|
||||
Create(view : View from V3d)
|
||||
---Purpose: A constructor of the selector,
|
||||
-- which initializes the classes
|
||||
-- by a view, where the user selects the voxels.
|
||||
returns Selector from Voxel;
|
||||
|
||||
Init(me : in out;
|
||||
view : View from V3d);
|
||||
---Purpose: Initializes the selector by a view,
|
||||
-- where the user selects the voxels.
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : BoolDS from Voxel);
|
||||
---Purpose: Defines the voxels (1bit).
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : ColorDS from Voxel);
|
||||
---Purpose: Defines the voxels (4bit).
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : ROctBoolDS from Voxel);
|
||||
---Purpose: Defines the voxels (1bit recursive splitting).
|
||||
|
||||
Detect(me : in out;
|
||||
winx : Integer from Standard;
|
||||
winy : Integer from Standard;
|
||||
ix : out Integer from Standard;
|
||||
iy : out Integer from Standard;
|
||||
iz : out Integer from Standard)
|
||||
---Purpose: Detects a voxel under the mouse cursor.
|
||||
returns Boolean from Standard;
|
||||
|
||||
fields
|
||||
|
||||
myView : View from V3d;
|
||||
myVoxels : Address from Standard;
|
||||
myIsBool : Integer from Standard; -- 0 - ColorDS, 1 - BoolDS, 2 - ROctBoolDS
|
||||
|
||||
end Selector;
|
569
src/Voxel/Voxel_Selector.cxx
Executable file
569
src/Voxel/Voxel_Selector.cxx
Executable file
@@ -0,0 +1,569 @@
|
||||
// File: Voxel_Selector.cxx
|
||||
// Created: Wed Jul 30 16:46:13 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_Selector.ixx>
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
|
||||
#include <IntAna_Quadric.hxx>
|
||||
#include <IntAna_IntConicQuad.hxx>
|
||||
|
||||
#include <TColStd_MapOfInteger.hxx>
|
||||
|
||||
Voxel_Selector::Voxel_Selector():myVoxels(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Voxel_Selector::Voxel_Selector(const Handle(V3d_View)& view):myView(view),myVoxels(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Voxel_Selector::Init(const Handle(V3d_View)& view)
|
||||
{
|
||||
myView = view;
|
||||
}
|
||||
|
||||
void Voxel_Selector::SetVoxels(const Voxel_BoolDS& voxels)
|
||||
{
|
||||
myIsBool = 1;
|
||||
myVoxels = (void*) &voxels;
|
||||
}
|
||||
|
||||
void Voxel_Selector::SetVoxels(const Voxel_ColorDS& voxels)
|
||||
{
|
||||
myIsBool = 0;
|
||||
myVoxels = (void*) &voxels;
|
||||
}
|
||||
|
||||
void Voxel_Selector::SetVoxels(const Voxel_ROctBoolDS& voxels)
|
||||
{
|
||||
myIsBool = 2;
|
||||
myVoxels = (void*) &voxels;
|
||||
}
|
||||
|
||||
// This function is copied from ViewerTest_RelationCommands.cxx
|
||||
static Standard_Boolean ComputeIntersection(const gp_Lin& L,const gp_Pln& ThePl, gp_Pnt& TheInter)
|
||||
{
|
||||
static IntAna_Quadric TheQuad;
|
||||
TheQuad.SetQuadric(ThePl);
|
||||
static IntAna_IntConicQuad QQ;
|
||||
QQ.Perform(L,TheQuad);
|
||||
if(QQ.IsDone()){
|
||||
if(QQ.NbPoints()>0){
|
||||
TheInter = QQ.Point(1);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
static inline Standard_Integer GetIVoxel(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
|
||||
const Standard_Integer nbx, const Standard_Integer nbxy)
|
||||
{
|
||||
return ix + iy * nbx + iz * nbxy;
|
||||
}
|
||||
|
||||
static inline Standard_Boolean Get(const Standard_Address voxels, const Standard_Integer isBool,
|
||||
const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz)
|
||||
{
|
||||
switch (isBool)
|
||||
{
|
||||
case 0:
|
||||
return ((Voxel_ColorDS*) voxels)->Get(ix, iy, iz) > 0;
|
||||
case 1:
|
||||
return ((Voxel_BoolDS*) voxels)->Get(ix, iy, iz);
|
||||
case 2:
|
||||
{
|
||||
Standard_Integer deepness = ((Voxel_ROctBoolDS*) voxels)->Deepness(ix, iy, iz);
|
||||
switch (deepness)
|
||||
{
|
||||
case 0:
|
||||
return ((Voxel_ROctBoolDS*) voxels)->Get(ix, iy, iz);
|
||||
case 1:
|
||||
{
|
||||
for (Standard_Integer i = 0; i < 8; i++)
|
||||
{
|
||||
if (((Voxel_ROctBoolDS*) voxels)->Get(ix, iy, iz, i) == Standard_True)
|
||||
return Standard_True;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
for (Standard_Integer i = 0; i < 8; i++)
|
||||
{
|
||||
for (Standard_Integer j = 0; j < 8; j++)
|
||||
{
|
||||
if (((Voxel_ROctBoolDS*) voxels)->Get(ix, iy, iz, i, j) == Standard_True)
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Selector::Detect(const Standard_Integer winx, const Standard_Integer winy,
|
||||
Standard_Integer& ixdetect, Standard_Integer& iydetect, Standard_Integer& izdetect)
|
||||
{
|
||||
ixdetect = -1; iydetect = -1; izdetect = -1;
|
||||
if (myView.IsNull() || !myVoxels)
|
||||
return Standard_False;
|
||||
|
||||
Voxel_DS* ds = 0;
|
||||
switch (myIsBool)
|
||||
{
|
||||
case 0:
|
||||
ds = (Voxel_ColorDS*) myVoxels;
|
||||
break;
|
||||
case 1:
|
||||
ds = (Voxel_BoolDS*) myVoxels;
|
||||
break;
|
||||
case 2:
|
||||
ds = (Voxel_ROctBoolDS*) myVoxels;
|
||||
break;
|
||||
}
|
||||
Standard_Integer nbx = ds->GetNbX(), nby = ds->GetNbY(), nbz = ds->GetNbZ(), nbxy = nbx * nby;
|
||||
|
||||
// Construct a line perpendicular to the screen
|
||||
Standard_Real eyex, eyey, eyez, nx, ny, nz;
|
||||
myView->Convert(winx, winy, eyex, eyey, eyez);
|
||||
myView->Proj(nx, ny, nz);
|
||||
gp_Pnt peye(eyex, eyey, eyez);
|
||||
gp_Lin line(peye, gp_Dir(nx, ny, nz));
|
||||
|
||||
// Find the first voxel meeting the line at entrance to the cube of voxels.
|
||||
// Construct planes of the cube of voxels
|
||||
Standard_Real xstart = ds->GetX(), ystart = ds->GetY(), zstart = ds->GetZ();
|
||||
Standard_Real xlen = ds->GetXLen(), ylen = ds->GetYLen(), zlen = ds->GetZLen();
|
||||
Standard_Real xend = xstart + xlen, yend = ystart + ylen, zend = zstart + zlen;
|
||||
gp_Pln xplane_minus(gp_Pnt(xstart, ystart, zstart), -gp::DX());
|
||||
gp_Pln xplane_plus (gp_Pnt(xend, ystart, zstart), gp::DX());
|
||||
gp_Pln yplane_minus(gp_Pnt(xstart, ystart, zstart), -gp::DY());
|
||||
gp_Pln yplane_plus (gp_Pnt(xstart, yend, zstart), gp::DY());
|
||||
gp_Pln zplane_minus(gp_Pnt(xstart, ystart, zstart), -gp::DZ());
|
||||
gp_Pln zplane_plus (gp_Pnt(xstart, ystart, zend), gp::DZ());
|
||||
// Intersect the planes with the line.
|
||||
gp_Pnt pintersection, p;
|
||||
Standard_Real depth = DBL_MAX, d;
|
||||
Standard_Integer iplane = -1; // not found
|
||||
if (ComputeIntersection(line, xplane_minus, p)) // -X
|
||||
{
|
||||
if (p.Y() >= ystart && p.Y() <= yend &&
|
||||
p.Z() >= zstart && p.Z() <= zend)
|
||||
{
|
||||
p.SetX(xstart);
|
||||
depth = peye.SquareDistance(p);
|
||||
iplane = 0;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
if (ComputeIntersection(line, xplane_plus, p)) // +X
|
||||
{
|
||||
if (p.Y() >= ystart && p.Y() <= yend &&
|
||||
p.Z() >= zstart && p.Z() <= zend)
|
||||
{
|
||||
d = peye.SquareDistance(p);
|
||||
if (d < depth)
|
||||
{
|
||||
p.SetX(xend);
|
||||
depth = d;
|
||||
iplane = 1;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComputeIntersection(line, yplane_minus, p)) // -Y
|
||||
{
|
||||
if (p.X() >= xstart && p.X() <= xend &&
|
||||
p.Z() >= zstart && p.Z() <= zend)
|
||||
{
|
||||
d = peye.SquareDistance(p);
|
||||
if (d < depth)
|
||||
{
|
||||
p.SetY(ystart);
|
||||
depth = d;
|
||||
iplane = 2;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComputeIntersection(line, yplane_plus, p)) // +Y
|
||||
{
|
||||
if (p.X() >= xstart && p.X() <= xend &&
|
||||
p.Z() >= zstart && p.Z() <= zend)
|
||||
{
|
||||
d = peye.SquareDistance(p);
|
||||
if (d < depth)
|
||||
{
|
||||
p.SetY(yend);
|
||||
depth = d;
|
||||
iplane = 3;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComputeIntersection(line, zplane_minus, p)) // -Z
|
||||
{
|
||||
if (p.X() >= xstart && p.X() <= xend &&
|
||||
p.Y() >= ystart && p.Y() <= yend)
|
||||
{
|
||||
d = peye.SquareDistance(p);
|
||||
if (d < depth)
|
||||
{
|
||||
p.SetZ(zstart);
|
||||
depth = d;
|
||||
iplane = 4;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ComputeIntersection(line, zplane_plus, p)) // +Z
|
||||
{
|
||||
if (p.X() >= xstart && p.X() <= xend &&
|
||||
p.Y() >= ystart && p.Y() <= yend)
|
||||
{
|
||||
d = peye.SquareDistance(p);
|
||||
if (d < depth)
|
||||
{
|
||||
p.SetZ(zend);
|
||||
depth = d;
|
||||
iplane = 5;
|
||||
pintersection = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find the voxel on the detected plane
|
||||
if (iplane == -1)
|
||||
return Standard_False;
|
||||
Standard_Integer ix, iy, iz;
|
||||
if (!ds->GetVoxel(pintersection.X(), pintersection.Y(), pintersection.Z(), ix, iy, iz))
|
||||
return Standard_False;
|
||||
ixdetect = ix; iydetect = iy; izdetect = iz;
|
||||
|
||||
// Find a non-zero voxel at the line
|
||||
Standard_Real xmin = xlen / Standard_Real(nbx),
|
||||
ymin = ylen / Standard_Real(nby),
|
||||
zmin = zlen / Standard_Real(nbz),
|
||||
vmin = sqrt(xmin * xmin + ymin * ymin + zmin * zmin) / 2.0;
|
||||
Standard_Real xc, yc, zc, dist, distmin = DBL_MAX;
|
||||
TColStd_MapOfInteger passed;
|
||||
while (!Get(myVoxels, myIsBool, ixdetect, iydetect, izdetect))
|
||||
{
|
||||
// Memorize already checked voxels
|
||||
if (!passed.Add(GetIVoxel(ixdetect, iydetect, izdetect, nbx, nbxy)))
|
||||
return Standard_False;
|
||||
|
||||
distmin = DBL_MAX;
|
||||
ix = ixdetect; iy = iydetect; iz = izdetect;
|
||||
|
||||
//1: -X neighbour
|
||||
if (ix - 1 >= 0 && !passed.Contains(GetIVoxel(ix - 1, iy, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//2: +X neighbour
|
||||
if (ix + 1 < nbx && !passed.Contains(GetIVoxel(ix + 1, iy, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//3: -Y neighbour
|
||||
if (iy - 1 >= 0 && !passed.Contains(GetIVoxel(ix, iy - 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy - 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy - 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//4: +Y neighbour
|
||||
if (iy + 1 < nby && !passed.Contains(GetIVoxel(ix, iy + 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy + 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy + 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//5: -Z neighbour
|
||||
if (iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix, iy, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//6: +Z neighbour
|
||||
if (iz + 1 < nbz && !passed.Contains(GetIVoxel(ix, iy, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
// Diagonal voxels
|
||||
//7: -X-Y neighbour
|
||||
if (ix - 1 >= 0 && iy - 1 >= 0 && !passed.Contains(GetIVoxel(ix - 1, iy - 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy - 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy - 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//8: -X-Z neighbour
|
||||
if (ix - 1 >= 0 && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix - 1, iy, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//9: -Y-Z neighbour
|
||||
if (iy - 1 >= 0 && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix, iy - 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy - 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy - 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
//10: +X-Y neighbour
|
||||
if (ix + 1 < nbx && iy - 1 >= 0 && !passed.Contains(GetIVoxel(ix + 1, iy - 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy - 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy - 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//11: +X-Z neighbour
|
||||
if (ix + 1 < nbx && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix + 1, iy, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//12: +Y-Z neighbour
|
||||
if (iy + 1 < nby && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix, iy + 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy + 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy + 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
//13: -X+Y neighbour
|
||||
if (ix - 1 >= 0 && iy + 1 < nby && !passed.Contains(GetIVoxel(ix - 1, iy + 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy + 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy + 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//14: -X+Z neighbour
|
||||
if (ix - 1 >= 0 && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix - 1, iy, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//15: -Y+Z neighbour
|
||||
if (iy - 1 >= 0 && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix, iy - 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy - 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy - 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
//16: +X+Y neighbour
|
||||
if (ix + 1 < nbx && iy + 1 < nby && !passed.Contains(GetIVoxel(ix + 1, iy + 1, iz, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy + 1, iz, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy + 1; izdetect = iz;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//17: +X+Z neighbour
|
||||
if (ix + 1 < nbx && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix + 1, iy, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//18: +Y+Z neighbour
|
||||
if (iy + 1 < nby && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix, iy + 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix, iy + 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix; iydetect = iy + 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
// Farest neighbours
|
||||
//19: -X-Y-Z neighbour
|
||||
if (ix - 1 >= 0 && iy - 1 >= 0 && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix - 1, iy - 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy - 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy - 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//20: +X-Y-Z neighbour
|
||||
if (ix + 1 < nbx && iy - 1 >= 0 && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix + 1, iy - 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy - 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy - 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//21: -X+Y-Z neighbour
|
||||
if (ix - 1 >= 0 && iy + 1 < nby && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix - 1, iy + 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy + 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy + 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//22: -X-Y+Z neighbour
|
||||
if (ix - 1 >= 0 && iy - 1 >= 0 && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix - 1, iy - 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy - 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy - 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//23: +X+Y-Z neighbour
|
||||
if (ix + 1 < nbx && iy + 1 < nby && iz - 1 >= 0 && !passed.Contains(GetIVoxel(ix + 1, iy + 1, iz - 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy + 1, iz - 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy + 1; izdetect = iz - 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//24: +X-Y+Z neighbour
|
||||
if (ix + 1 < nbx && iy - 1 >= 0 && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix + 1, iy - 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy - 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy - 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//25: -X+Y+Z neighbour
|
||||
if (ix - 1 >= 0 && iy + 1 < nby && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix - 1, iy + 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix - 1, iy + 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix - 1; iydetect = iy + 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
//26: +X+Y+Z neighbour
|
||||
if (ix + 1 < nbx && iy + 1 < nby && iz + 1 < nbz && !passed.Contains(GetIVoxel(ix + 1, iy + 1, iz + 1, nbx, nbxy)))
|
||||
{
|
||||
ds->GetCenter(ix + 1, iy + 1, iz + 1, xc, yc, zc);
|
||||
dist = line.Distance(gp_Pnt(xc, yc, zc));
|
||||
if (dist < vmin && dist < distmin)
|
||||
{
|
||||
ixdetect = ix + 1; iydetect = iy + 1; izdetect = iz + 1;
|
||||
distmin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of while (zero-voxel...
|
||||
|
||||
if (!Get(myVoxels, myIsBool, ixdetect, iydetect, izdetect))
|
||||
return Standard_False;
|
||||
return Standard_True;
|
||||
}
|
35
src/Voxel/Voxel_SplitData.cdl
Executable file
35
src/Voxel/Voxel_SplitData.cdl
Executable file
@@ -0,0 +1,35 @@
|
||||
-- File: Voxel_SplitData.cdl
|
||||
-- Created: Sun Sep 01 10:36:25 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
private class SplitData from Voxel
|
||||
|
||||
---Purpose: A container of split information.
|
||||
-- An instance of this class is used as a slice
|
||||
-- in inner representation of recursive octtree voxels.
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns SplitData from Voxel;
|
||||
|
||||
GetValues(me : in out)
|
||||
---Purpose: Gives access to the values.
|
||||
---C++: return &
|
||||
returns Address from Standard;
|
||||
|
||||
GetSplitData(me : in out)
|
||||
---Purpose: Gives access to the next split data.
|
||||
---C++: return &
|
||||
returns Address from Standard;
|
||||
|
||||
fields
|
||||
|
||||
myValues : Address from Standard;
|
||||
mySplitData : Address from Standard;
|
||||
|
||||
end SplitData;
|
||||
|
21
src/Voxel/Voxel_SplitData.cxx
Executable file
21
src/Voxel/Voxel_SplitData.cxx
Executable file
@@ -0,0 +1,21 @@
|
||||
// File: Voxel_SplitData.cxx
|
||||
// Created: Mon Sep 01 10:47:22 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_SplitData.ixx>
|
||||
|
||||
Voxel_SplitData::Voxel_SplitData():myValues(0),mySplitData(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Standard_Address& Voxel_SplitData::GetValues()
|
||||
{
|
||||
return myValues;
|
||||
}
|
||||
|
||||
Standard_Address& Voxel_SplitData::GetSplitData()
|
||||
{
|
||||
return mySplitData;
|
||||
}
|
42
src/Voxel/Voxel_TypeDef.hxx
Executable file
42
src/Voxel/Voxel_TypeDef.hxx
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef _VOXEL_TYPEDEF_HXX_
|
||||
#define _VOXEL_TYPEDEF_HXX_
|
||||
|
||||
// Basic data types
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Standard_Integer ix;
|
||||
Standard_Integer iy;
|
||||
Standard_Integer iz;
|
||||
} iXYZ;
|
||||
|
||||
|
||||
// Maps and Tables
|
||||
|
||||
inline Standard_Integer HashCode(const iXYZ& me, const Standard_Integer upper)
|
||||
{
|
||||
return (Abs(me.ix + me.iy + me.iz) % upper) + 1;
|
||||
}
|
||||
|
||||
inline Standard_Boolean IsEqual(const iXYZ& one, const iXYZ& two)
|
||||
{
|
||||
return one.ix == two.ix && one.iy == two.iy && one.iz == two.iz;
|
||||
}
|
||||
|
||||
#include <NCollection_DefineBaseCollection.hxx>
|
||||
DEFINE_BASECOLLECTION(iXYZbase, iXYZ)
|
||||
|
||||
#include <NCollection_DefineDataMap.hxx>
|
||||
DEFINE_DATAMAP(iXYZIndex, iXYZbase, iXYZ, Standard_Integer)
|
||||
DEFINE_DATAMAP(iXYZBool, iXYZbase, iXYZ, Standard_Byte)
|
||||
|
||||
// Defines
|
||||
|
||||
#define VOXELS "Voxels"
|
||||
#define ASCII "Ascii"
|
||||
#define BINARY "Binary"
|
||||
#define BOOL "Bool"
|
||||
#define COLOR "Color"
|
||||
#define FLOAT "Float"
|
||||
|
||||
#endif // _VOXEL_TYPEDEF_HXX_
|
114
src/Voxel/Voxel_VisData.h
Executable file
114
src/Voxel/Voxel_VisData.h
Executable file
@@ -0,0 +1,114 @@
|
||||
#ifndef _VOXEL_VISDATA_H_
|
||||
#define _VOXEL_VISDATA_H_
|
||||
|
||||
#include <Quantity_Color.hxx>
|
||||
#include <Quantity_HArray1OfColor.hxx>
|
||||
#include <TShort_HArray1OfShortReal.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <TColgp_HArray1OfDir.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
|
||||
#include <Voxel_BoolDS.hxx>
|
||||
#include <Voxel_ColorDS.hxx>
|
||||
#include <Voxel_ROctBoolDS.hxx>
|
||||
#include <Voxel_VoxelDisplayMode.hxx>
|
||||
|
||||
enum VoxelDirection
|
||||
{
|
||||
None,
|
||||
Xminus,
|
||||
Xplus,
|
||||
Yminus,
|
||||
Yplus,
|
||||
Zminus,
|
||||
Zplus
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
/* Display mode */
|
||||
Voxel_VoxelDisplayMode myDisplayMode;
|
||||
|
||||
/* Range of displayed values */
|
||||
/* BoolDS */
|
||||
/* No range */
|
||||
/* ColorDS */
|
||||
Standard_Byte myColorMinValue;
|
||||
Standard_Byte myColorMaxValue;
|
||||
|
||||
/* Range of displayed size */
|
||||
Standard_Real myDisplayedXMin;
|
||||
Standard_Real myDisplayedXMax;
|
||||
Standard_Real myDisplayedYMin;
|
||||
Standard_Real myDisplayedYMax;
|
||||
Standard_Real myDisplayedZMin;
|
||||
Standard_Real myDisplayedZMax;
|
||||
|
||||
/* Colors */
|
||||
Quantity_Color myColor;
|
||||
Handle(Quantity_HArray1OfColor) myColors;
|
||||
|
||||
/* Size, width... */
|
||||
Standard_Real myPointSize;
|
||||
Standard_Integer myQuadrangleSize; /* 0% .. 100% */
|
||||
Standard_Byte mySmoothPoints;
|
||||
|
||||
/* Transparency */
|
||||
Standard_Real myTransparency;
|
||||
|
||||
/* GL lists of each display mode */
|
||||
/* BoolDS */
|
||||
/* POINTS */
|
||||
Standard_Integer myBoolPointsList;
|
||||
Standard_Byte myBoolPointsFirst;
|
||||
/* NEAREST POINTS */
|
||||
Standard_Integer myBoolNearestPointsList[7];
|
||||
Standard_Byte myBoolNearestPointsFirst;
|
||||
/* ColorDS */
|
||||
/* POINTS */
|
||||
Standard_Integer myColorPointsList;
|
||||
Standard_Byte myColorPointsFirst;
|
||||
/* NEAREST POINTS */
|
||||
Standard_Integer myColorNearestPointsList[7];
|
||||
Standard_Byte myColorNearestPointsFirst;
|
||||
/* ROctBoolDS */
|
||||
/* POINTS */
|
||||
Standard_Integer myROctBoolPointsList;
|
||||
Standard_Byte myROctBoolPointsFirst;
|
||||
/* NEAREST POINTS */
|
||||
Standard_Integer myROctBoolNearestPointsList[7];
|
||||
Standard_Byte myROctBoolNearestPointsFirst;
|
||||
/* TRIANGULATION */
|
||||
Standard_Integer myTriangulationList;
|
||||
/* Usage of GL lists */
|
||||
Standard_Byte myUsageOfGLlists;
|
||||
|
||||
/* Degenerate mode */
|
||||
Standard_Byte myDegenerateMode;
|
||||
|
||||
/* Highlighted voxel */
|
||||
Standard_Integer myHighlightx;
|
||||
Standard_Integer myHighlighty;
|
||||
Standard_Integer myHighlightz;
|
||||
|
||||
} DisplayData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
// Voxels
|
||||
Voxel_BoolDS* myBoolVoxels;
|
||||
Voxel_ColorDS* myColorVoxels;
|
||||
Voxel_ROctBoolDS* myROctBoolVoxels;
|
||||
|
||||
// Triangulation
|
||||
Handle(Poly_Triangulation) myTriangulation;
|
||||
Handle(TColgp_HArray1OfDir) myNormalsOfNodes;
|
||||
|
||||
// Display
|
||||
DisplayData myDisplay;
|
||||
|
||||
} Voxel_VisData;
|
||||
|
||||
#endif // _VOXEL_VISDATA_H_
|
97
src/Voxel/Voxel_Writer.cdl
Executable file
97
src/Voxel/Voxel_Writer.cdl
Executable file
@@ -0,0 +1,97 @@
|
||||
-- File: Voxel_Writer.cdl
|
||||
-- Created: Wed Aug 28 11:23:33 2008
|
||||
-- Author: Vladislav ROMASHKO
|
||||
-- <vladislav.romashko@opencascade.com>
|
||||
---Copyright: Open CASCADE S.A.
|
||||
|
||||
class Writer from Voxel
|
||||
|
||||
---Purpose: Writes a cube of voxels on disk.
|
||||
|
||||
uses
|
||||
|
||||
VoxelFileFormat from Voxel,
|
||||
BoolDS from Voxel,
|
||||
ColorDS from Voxel,
|
||||
FloatDS from Voxel,
|
||||
ExtendedString from TCollection
|
||||
|
||||
is
|
||||
|
||||
Create
|
||||
---Purpose: An empty constructor.
|
||||
returns Writer from Voxel;
|
||||
|
||||
SetFormat(me : in out;
|
||||
format : VoxelFileFormat from Voxel);
|
||||
---Purpose: Defines the file format for voxels.
|
||||
-- ASCII - slow and occupies more space on disk.
|
||||
-- BINARY - fast and occupies less space on disk.
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : BoolDS from Voxel);
|
||||
---Purpose: Defines the voxels (1bit).
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : ColorDS from Voxel);
|
||||
---Purpose: Defines the voxels (4bit).
|
||||
|
||||
SetVoxels(me : in out;
|
||||
voxels : FloatDS from Voxel);
|
||||
---Purpose: Defines the voxels (4bytes).
|
||||
|
||||
Write(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes the voxels on disk
|
||||
-- using the defined format and file name.
|
||||
returns Boolean from Standard;
|
||||
|
||||
|
||||
---Private area
|
||||
-- ============
|
||||
|
||||
WriteBoolAsciiVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 1bit voxels on disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
WriteColorAsciiVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 4bit voxels on disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
WriteFloatAsciiVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 4bytes voxels on disk in ASCII format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
WriteBoolBinaryVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 1bit voxels on disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
WriteColorBinaryVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 4bit voxels on disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
WriteFloatBinaryVoxels(me;
|
||||
file : ExtendedString from TCollection)
|
||||
---Purpose: Writes 4bytes voxels on disk in BINARY format.
|
||||
returns Boolean from Standard
|
||||
is private;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
myFormat : VoxelFileFormat from Voxel;
|
||||
myBoolVoxels : Address from Standard;
|
||||
myColorVoxels : Address from Standard;
|
||||
myFloatVoxels : Address from Standard;
|
||||
|
||||
end Writer;
|
427
src/Voxel/Voxel_Writer.cxx
Executable file
427
src/Voxel/Voxel_Writer.cxx
Executable file
@@ -0,0 +1,427 @@
|
||||
// File: Voxel_Writer.cxx
|
||||
// Created: Wed Aug 28 14:36:15 2008
|
||||
// Author: Vladislav ROMASHKO
|
||||
// <vladislav.romashko@opencascade.com>
|
||||
|
||||
#include <Voxel_Writer.ixx>
|
||||
#include <Voxel_TypeDef.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
Voxel_Writer::Voxel_Writer():myFormat(Voxel_VFF_ASCII),myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Voxel_Writer::SetFormat(const Voxel_VoxelFileFormat format)
|
||||
{
|
||||
myFormat = format;
|
||||
}
|
||||
|
||||
void Voxel_Writer::SetVoxels(const Voxel_BoolDS& voxels)
|
||||
{
|
||||
myBoolVoxels = (Standard_Address) &voxels;
|
||||
myColorVoxels = 0;
|
||||
myFloatVoxels = 0;
|
||||
}
|
||||
|
||||
void Voxel_Writer::SetVoxels(const Voxel_ColorDS& voxels)
|
||||
{
|
||||
myBoolVoxels = 0;
|
||||
myColorVoxels = (Standard_Address) &voxels;
|
||||
myFloatVoxels = 0;
|
||||
}
|
||||
|
||||
void Voxel_Writer::SetVoxels(const Voxel_FloatDS& voxels)
|
||||
{
|
||||
myBoolVoxels = 0;
|
||||
myColorVoxels = 0;
|
||||
myFloatVoxels = (Standard_Address) &voxels;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::Write(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
switch (myFormat)
|
||||
{
|
||||
case Voxel_VFF_ASCII:
|
||||
{
|
||||
if (myBoolVoxels)
|
||||
return WriteBoolAsciiVoxels(file);
|
||||
else if (myColorVoxels)
|
||||
return WriteColorAsciiVoxels(file);
|
||||
else if (myFloatVoxels)
|
||||
return WriteFloatAsciiVoxels(file);
|
||||
}
|
||||
case Voxel_VFF_BINARY:
|
||||
{
|
||||
if (myBoolVoxels)
|
||||
return WriteBoolBinaryVoxels(file);
|
||||
else if (myColorVoxels)
|
||||
return WriteColorBinaryVoxels(file);
|
||||
else if (myFloatVoxels)
|
||||
return WriteFloatBinaryVoxels(file);
|
||||
}
|
||||
}
|
||||
|
||||
// No voxels or no format description is found:
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteBoolAsciiVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_BoolDS* ds = (Voxel_BoolDS*) myBoolVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "w+");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, ASCII);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, BOOL);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ());
|
||||
fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen());
|
||||
fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ());
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_BoolDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 7]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_Byte**)ds->myData)[i1])
|
||||
{
|
||||
Standard_Boolean has_value = Standard_False;
|
||||
fprintf(f, "%d ", i1); // index of slice
|
||||
for (i2 = 0; i2 < 8; i2++)
|
||||
{
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2];
|
||||
if (value)
|
||||
{
|
||||
has_value = Standard_True;
|
||||
fprintf(f, "%d %d\n", i2, value);
|
||||
}
|
||||
}
|
||||
if (!has_value)
|
||||
{
|
||||
fprintf(f, "0 0\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteColorAsciiVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_ColorDS* ds = (Voxel_ColorDS*) myColorVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "w+");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, ASCII);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, COLOR);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ());
|
||||
fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen());
|
||||
fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ());
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_ColorDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 2.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_Byte**)ds->myData)[i1])
|
||||
{
|
||||
Standard_Boolean has_value = Standard_False;
|
||||
fprintf(f, "%d ", i1); // index of slice
|
||||
for (i2 = 0; i2 < 32; i2++)
|
||||
{
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2];
|
||||
if (value)
|
||||
{
|
||||
has_value = Standard_True;
|
||||
fprintf(f, "%d %d\n", i2, value);
|
||||
}
|
||||
}
|
||||
if (!has_value)
|
||||
{
|
||||
fprintf(f, "0 0\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteFloatAsciiVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_FloatDS* ds = (Voxel_FloatDS*) myFloatVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "w+");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, ASCII);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, FLOAT);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ());
|
||||
fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen());
|
||||
fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ());
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_FloatDS.cxx:
|
||||
Standard_Integer nb_floats = ds->GetNbX() * ds->GetNbY() * ds->GetNbZ();
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_ShortReal**)ds->myData)[i1])
|
||||
{
|
||||
Standard_Boolean has_value = Standard_False;
|
||||
fprintf(f, "%d ", i1); // index of slice
|
||||
for (i2 = 0; i2 < 32; i2++)
|
||||
{
|
||||
Standard_ShortReal value = ((Standard_ShortReal*)((Standard_ShortReal**)ds->myData)[i1])[i2];
|
||||
if (value)
|
||||
{
|
||||
has_value = Standard_True;
|
||||
fprintf(f, "%d %g\n", i2, value);
|
||||
}
|
||||
}
|
||||
if (!has_value)
|
||||
{
|
||||
fprintf(f, "0 0\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteBoolBinaryVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_BoolDS* ds = (Voxel_BoolDS*) myBoolVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "wb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, BINARY);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, BOOL);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fwrite(&(ds->myX), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myY), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_BoolDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 8.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 7]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_Byte**)ds->myData)[i1])
|
||||
{
|
||||
for (i2 = 0; i2 < 8; i2++)
|
||||
{
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2];
|
||||
if (value)
|
||||
{
|
||||
fwrite(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&value, sizeof(Standard_Byte), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteColorBinaryVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_ColorDS* ds = (Voxel_ColorDS*) myColorVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "wb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, BINARY);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, COLOR);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fwrite(&(ds->myX), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myY), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_ColorDS.cxx:
|
||||
Standard_Integer nb_bytes = RealToInt(ceil(ds->myNbX * ds->myNbY * ds->myNbZ / 2.0));
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_Byte**)ds->myData)[i1])
|
||||
{
|
||||
for (i2 = 0; i2 < 32; i2++)
|
||||
{
|
||||
Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2];
|
||||
if (value)
|
||||
{
|
||||
fwrite(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&value, sizeof(Standard_Byte), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Boolean Voxel_Writer::WriteFloatBinaryVoxels(const TCollection_ExtendedString& file) const
|
||||
{
|
||||
Voxel_FloatDS* ds = (Voxel_FloatDS*) myFloatVoxels;
|
||||
if (!ds->myData)
|
||||
return Standard_False;
|
||||
|
||||
// Open file for writing
|
||||
FILE* f = fopen(TCollection_AsciiString(file, '?').ToCString(), "wb");
|
||||
if (!f)
|
||||
return Standard_False;
|
||||
|
||||
// Header: file format, type of voxels
|
||||
fprintf(f, VOXELS);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, BINARY);
|
||||
fprintf(f, " ");
|
||||
fprintf(f, FLOAT);
|
||||
fprintf(f, "\n");
|
||||
|
||||
// Location, size, number of splits
|
||||
fwrite(&(ds->myX), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myY), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f);
|
||||
fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f);
|
||||
|
||||
// Data
|
||||
// Copied from Voxel_FloatDS.cxx:
|
||||
Standard_Integer nb_floats = ds->myNbX * ds->myNbY * ds->myNbZ;
|
||||
Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
|
||||
// myData[0 .. nb_slices - 1][0 .. 31]
|
||||
if (nb_slices)
|
||||
{
|
||||
Standard_Integer i1 = 0, i2 = 0;
|
||||
Standard_Real small = Precision::Confusion() * Precision::Confusion();
|
||||
for (i1 = 0; i1 < nb_slices; i1++)
|
||||
{
|
||||
if (((Standard_ShortReal**)ds->myData)[i1])
|
||||
{
|
||||
for (i2 = 0; i2 < 32; i2++)
|
||||
{
|
||||
Standard_ShortReal value = ((Standard_ShortReal*)((Standard_ShortReal**)ds->myData)[i1])[i2];
|
||||
if (fabs(value) > small)
|
||||
{
|
||||
fwrite(&i1, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&i2, sizeof(Standard_Integer), 1, f);
|
||||
fwrite(&value, sizeof(Standard_ShortReal), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Standard_True;
|
||||
}
|
Reference in New Issue
Block a user