1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Voxels for AVD

Conflicts:
	src/Graphic3d/FILES
	src/Graphic3d/Graphic3d.cdl
	src/Graphic3d/Graphic3d_Group.cdl
	src/Graphic3d/Graphic3d_TransferFunction.cxx
	src/OpenGl/FILES
	src/Voxel/FILES
	src/Voxel/Voxel_BoolDS.cxx
	src/Voxel/Voxel_BooleanOperation.cxx
	src/Voxel/Voxel_CollisionDetection.cxx
	src/Voxel/Voxel_ColorDS.cxx
	src/Voxel/Voxel_DS.cxx
	src/Voxel/Voxel_FastConverter.cxx
	src/Voxel/Voxel_FloatDS.cxx
	src/Voxel/Voxel_Prs.cxx
	src/Voxel/Voxel_Prs.hxx
	src/Voxel/Voxel_ROctBoolDS.cxx
	src/Voxel/Voxel_Reader.cxx
	src/Voxel/Voxel_Selector.cxx
	src/Voxel/Voxel_Writer.cxx
This commit is contained in:
duv
2015-07-10 14:20:38 +03:00
committed by omy
parent 113d8db4f3
commit f9d060bd4f
55 changed files with 4134 additions and 6299 deletions

View File

@@ -101,6 +101,20 @@ protected:
};
//! 2D Axis aligned box on single precision reals.
typedef BVH_Box<Standard_ShortReal, 2> BVH_Box2f;
//! 3D Axis aligned box on single precision reals.
typedef BVH_Box<Standard_ShortReal, 3> BVH_Box3f;
//! 4D Axis aligned box on single precision reals.
typedef BVH_Box<Standard_ShortReal, 4> BVH_Box4f;
//! 2D Axis aligned box on double precision reals.
typedef BVH_Box<Standard_Real, 2> BVH_Box2d;
//! 3D Axis aligned box on double precision reals.
typedef BVH_Box<Standard_Real, 3> BVH_Box3d;
//! 4D Axis aligned box on double precision reals.
typedef BVH_Box<Standard_Real, 4> BVH_Box4d;
namespace BVH
{
//! Tool class for calculating box center along the given axis.

View File

@@ -173,3 +173,33 @@ Graphic3d_ViewAffinity.hxx
Graphic3d_WorldViewProjState.hxx
Graphic3d_ZLayerId.hxx
Graphic3d_ZLayerSettings.hxx
Graphic3d_Vertex.hxx
Graphic3d_Vertex.cxx
Graphic3d_MarkerImage.hxx
Graphic3d_MarkerImage.cxx
Graphic3d_ClipPlane.hxx
Graphic3d_ClipPlane.cxx
Graphic3d_SequenceOfGroup.hxx
Graphic3d_SequenceOfHClipPlane.hxx
Graphic3d_Camera.cxx
Graphic3d_Camera.hxx
Graphic3d_RenderingParams.hxx
Graphic3d_NMapOfTransient.hxx
Graphic3d_BSDF.hxx
Graphic3d_BSDF.cxx
Graphic3d_Volume.hxx
Graphic3d_Volume.cxx
Graphic3d_VolumeData.hxx
Graphic3d_VolumeData.cxx
Graphic3d_DenseVolumeData.hxx
Graphic3d_DenseVolumeData.lxx
Graphic3d_TransferFunction.hxx
Graphic3d_TransferFunction.cxx
Graphic3d_RgbaTransferFunction.hxx
Graphic3d_RgbaTransferFunction.lxx
Graphic3d_TransferFunctionNode.hxx
Graphic3d_TransferFunctionFilter.hxx
Graphic3d_TransferFunctionLinearFilter.hxx
Graphic3d_TransferFunctionLinearFilter.lxx
Graphic3d_TransferFunctionNearestFilter.hxx
Graphic3d_TransferFunctionNearestFilter.lxx

View File

@@ -0,0 +1,582 @@
-- Created on: 1993-03-31
-- Created by: NW,JPB,CAL
-- Copyright (c) 1993-1999 Matra Datavision
-- Copyright (c) 1999-2014 OPEN CASCADE SAS
--
-- This file is part of Open CASCADE Technology software library.
--
-- This library is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License version 2.1 as published
-- by the Free Software Foundation, with special exception defined in the file
-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-- distribution for complete text of the license and disclaimer of any warranty.
--
-- Alternatively, this file may be used under the terms of Open CASCADE
-- commercial license or contractual agreement.
-- Package : Graphic3d
-- Updated : Vendredi 2 Octobre 1992
-- Mercredi 31 Mars 1993
-- Mercredi 19 Janvier 1994
-- 1/08/97 ; PCT : Ajout texture mapping
-- 11/97 ; CAL : retrait de la dependance avec math
-- 11/97 ; CAL : retrait des DataStructure
-- 04/98 ; FGU : ajout champs 'TOR_EMISSION'
-- 16-09-98; BGN: (S3819) Ajout TypeOfTriedronEcho,
-- TypeOfTriedronPosition.
-- 22-09-98; BGN: S3989 (anciennement S3819): report
-- dans Aspect des TypeOfTriedron*
-- 26-03-99 : FMN ; Compatibilite ascendante:
-- Ajout des anciens noms de materiaux.
-- 09-04-99 : GG ; Compatibilite ascendante:
-- NameOfPhysicalMaterial disparait
-- 23-11-99 : GG ; Add material name DEFAULT
-- 16-06-2000 : ATS : Study G005: class ArrayOfPrimitives
-- and derivated used for model presentation.
-- Required: enumeration TypeOfPrimitive;
-- imported PrimitiveArray; class PrimitiveList.
-- 17-12-01 : GG ; IMP171201 : Add material name UserDefined
-- Thanks to Stephane ROUTELOUS
-- 20-01-2009 : ABD Integration support of system fonts (using FTGL and FreeType)
-- Objective : Specifications definitives
package Graphic3d
---Version:
---Purpose: This package permits the creation of 3d graphic objects
-- in a visualiser.
-- These objects, called structures, are composed of groups of
-- primitives and attributes.
-- The group is the smallest editable element of a structure.
-- A structure can be displayed, erased, high-lighted.
-- A transformation can be applied to it.
-- Structures can be connected to form a tree of structures,
-- composed by transformations.
-- The visualiser permits global manipulation of structures.
---Keywords: Structure, Group, Primitives, Line, Marker, Text,
-- FillAreas, Vertex, Vector, Material, Font, Shading
---Warning:
---References:
uses
TCollection,
TColStd,
TColgp,
OSD,
Quantity,
Aspect,
MMgt,
WNT,
Image,
gp,
Font,
Bnd
is
-----------------------
-- Category: Exceptions
-----------------------
exception AspectTextDefinitionError inherits OutOfRange;
---Category: Exceptions
exception CycleError inherits DomainError;
---Category: Exceptions
exception GroupDefinitionError inherits OutOfRange;
---Category: Exceptions
exception InitialisationError inherits OutOfRange;
---Category: Exceptions
exception MaterialDefinitionError inherits OutOfRange;
---Category: Exceptions
exception PriorityDefinitionError inherits OutOfRange;
---Category: Exceptions
exception StructureDefinitionError inherits OutOfRange;
---Category: Exceptions
exception TransformError inherits OutOfRange;
---Category: Exceptions
exception VectorError inherits OutOfRange;
---Category: Exceptions
-------------------------
-- Category: Enumerations
-------------------------
enumeration NameOfMaterial is
NOM_BRASS, -- laiton (PHYSIC)
NOM_BRONZE, -- bronze (PHYSIC)
NOM_COPPER, -- cuivre (PHYSIC)
NOM_GOLD, -- or (PHYSIC)
NOM_PEWTER, -- etain (PHYSIC)
NOM_PLASTER, -- platre (GENERIC)
NOM_PLASTIC, -- plastic (GENERIC)
NOM_SILVER, -- argent (PHYSIC)
NOM_STEEL, -- acier (PHYSIC)
NOM_STONE, -- pierre (PHYSIC)
NOM_SHINY_PLASTIC, -- plastique brillant (GENERIC)
NOM_SATIN, -- satin (GENERIC)
NOM_METALIZED, -- metallise New (GENERIC)
NOM_NEON_GNC, -- neon New (GENERIC)
NOM_CHROME, -- chrome New (PHYSIC)
NOM_ALUMINIUM, -- aluminium New (PHYSIC)
NOM_OBSIDIAN, -- obsidian New (PHYSIC)
NOM_NEON_PHC, -- neon New (PHYSIC)
NOM_JADE, -- jade New (PHYSIC)
NOM_CHARCOAL,
NOM_WATER,
NOM_GLASS,
NOM_DIAMOND,
NOM_DEFAULT,
NOM_UserDefined -- owner material
end NameOfMaterial;
---Purpose: Types of aspect materials.
---Category: Enumerations
enumeration TypeOfMaterial is MATERIAL_ASPECT, -- Materiel generique
MATERIAL_PHYSIC -- Materiel physique
end TypeOfMaterial;
---Purpose: Types of materials specifies if a material can change color.
---Category: Enumerations
enumeration NameOfTexture1D is NOT_1D_ELEVATION,
NOT_1D_UNKNOWN
end NameOfTexture1D;
---Purpose: Types of standard textures.
---Category: Enumerations
enumeration NameOfTexture2D is NOT_2D_MATRA,
NOT_2D_ALIENSKIN,
NOT_2D_BLUE_ROCK,
NOT_2D_BLUEWHITE_PAPER,
NOT_2D_BRUSHED,
NOT_2D_BUBBLES,
NOT_2D_BUMP,
NOT_2D_CAST,
NOT_2D_CHIPBD,
NOT_2D_CLOUDS,
NOT_2D_FLESH,
NOT_2D_FLOOR,
NOT_2D_GALVNISD,
NOT_2D_GRASS,
NOT_2D_ALUMINUM,
NOT_2D_ROCK,
NOT_2D_KNURL,
NOT_2D_MAPLE,
NOT_2D_MARBLE,
NOT_2D_MOTTLED,
NOT_2D_RAIN,
NOT_2D_UNKNOWN
end NameOfTexture2D;
---Purpose: Types of standard textures.
---Category: Enumerations
enumeration NameOfTextureEnv is NOT_ENV_CLOUDS,
NOT_ENV_CV,
NOT_ENV_MEDIT,
NOT_ENV_PEARL,
NOT_ENV_SKY1,
NOT_ENV_SKY2,
NOT_ENV_LINES,
NOT_ENV_ROAD,
NOT_ENV_UNKNOWN
end NameOfTextureEnv;
---Purpose: Types of standard textures.
---Category: Enumerations
enumeration TypeOfTexture is TOT_1D,
TOT_2D,
TOT_2D_MIPMAP;
---Purpose: Type of the texture file format.
---Category: Enumerations
enumeration TypeOfTextureMode is TOTM_OBJECT,
TOTM_SPHERE,
TOTM_EYE,
TOTM_MANUAL,
TOTM_SPRITE;
---Purpose: Type of the texture projection.
---Category: Enumerations
enumeration TypeOfTextureFilter is TOTF_NEAREST,
TOTF_BILINEAR,
TOTF_TRILINEAR;
---Purpose: Type of the texture filter.
-- Notice that for textures without mipmaps linear interpolation will be used instead of TOTF_BILINEAR and TOTF_TRILINEAR.
---Category: Enumerations
enumeration LevelOfTextureAnisotropy is LOTA_OFF,
LOTA_FAST,
LOTA_MIDDLE,
LOTA_QUALITY;
---Purpose: Level of anisotropy filter.
-- Notice that actual quality depends on hardware capabilities!
---Category: Enumerations
enumeration NameOfTexturePlane is NOTP_XY,
NOTP_YZ,
NOTP_ZX,
NOTP_UNKNOWN;
---Purpose: Type of the texture projection plane for both S and T texture coordinate.
---Category: Enumerations
enumeration TypeOfComposition is TOC_REPLACE,
TOC_POSTCONCATENATE
end TypeOfComposition;
---Purpose: To manage the transformation matrices of structures.
---Category: Enumerations
enumeration TypeOfConnection is TOC_ANCESTOR,
TOC_DESCENDANT
end TypeOfConnection;
---Purpose: To manage the connections between the structures.
---Category: Enumerations
enumeration TypeOfPolygon is TOP_UNKNOWN,
TOP_COMPLEX,
TOP_CONCAVE,
TOP_CONVEX
end TypeOfPolygon;
---Purpose: The type of polygon in a group in a structure.
---Category: Enumerations
enumeration TypeOfPrimitive is TOP_UNDEFINED,
TOP_POLYLINE,
TOP_POLYGON,
TOP_TRIANGLEMESH,
TOP_QUADRANGLEMESH,
TOP_TEXT,
TOP_MARKER,
TOP_PARRAY
end TypeOfPrimitive;
---Purpose: The type of primitive in a group in a structure.
---Category: Enumerations
enumeration TypeOfPrimitiveArray is TOPA_UNDEFINED,
TOPA_POINTS,
TOPA_POLYLINES,
TOPA_SEGMENTS,
TOPA_POLYGONS,
TOPA_TRIANGLES,
TOPA_QUADRANGLES,
TOPA_TRIANGLESTRIPS,
TOPA_QUADRANGLESTRIPS,
TOPA_TRIANGLEFANS
end TypeOfPrimitiveArray;
---Purpose: The type of primitive array in a group in a structure.
---Category: Enumerations
enumeration TypeOfReflection is TOR_AMBIENT,
TOR_DIFFUSE,
TOR_SPECULAR,
TOR_EMISSION
end TypeOfReflection;
---Purpose: Nature of the reflection of a material.
---Category: Enumerations
enumeration TypeOfStructure is TOS_WIREFRAME,
TOS_SHADING,
TOS_COMPUTED,
TOS_ALL
end TypeOfStructure;
---Purpose: Structural attribute indicating if it can be displayed
-- in wireframe, shadow mode, or both.
---Category: Enumerations
enumeration TextPath is TP_UP,
TP_DOWN,
TP_LEFT,
TP_RIGHT
end TextPath;
---Purpose: Direction in which text is displayed.
---Category: Enumerations
enumeration HorizontalTextAlignment is HTA_LEFT,
HTA_CENTER,
HTA_RIGHT
end HorizontalTextAlignment;
---Purpose: Defines the horizontal position of the text
-- relative to its anchor.
---Category: Enumerations
enumeration VerticalTextAlignment is VTA_BOTTOM,
VTA_CENTER,
VTA_TOP
end VerticalTextAlignment;
---Purpose: Defines the vertical position of the text
-- relative to its anchor.
---Category: Enumerations
enumeration GroupAspect is ASPECT_LINE,
ASPECT_TEXT,
ASPECT_MARKER,
ASPECT_FILL_AREA
end GroupAspect;
---Purpose: Identifies primitives aspects defined per group.
-- - ASPECT_LINE: aspect for line primitives;
-- - ASPECT_TEXT: aspect for text primitives;
-- - ASPECT_MARKER: aspect for marker primitives;
-- - ASPECT_FILL_AREA: aspect for face primitives.
enumeration RenderingMode is
RM_RASTERIZATION, RM_RAYTRACING
end RenderingMode;
---Purpose: Describes rendering modes.
-- - RM_RASTERIZATION: enables OpenGL rasterization mode;
-- - RM_RAYTRACING: enables GPU ray-tracing mode.
enumeration TypeOfBackground is
TOB_NONE, TOB_GRADIENT, TOB_TEXTURE
end TypeOfBackground;
---Purpose: Describes type of view background.
---------------------------
-- Category: Imported types
---------------------------
imported BndBox4f;
---Purpose: Redefines BVH_Box<Standard_ShortReal, 4> for AABB representation
---Category: Imported types
imported Buffer;
imported Buffer_Handle;
imported BoundBuffer;
imported BoundBuffer_Handle;
imported IndexBuffer;
imported IndexBuffer_Handle;
imported BndBox4d;
imported BufferType;
imported BSDF;
imported CBitFields20;
---Category: Imported types
imported CBitFields16;
---Category: Imported types
imported CBitFields8;
---Category: Imported types
imported CBitFields4;
---Category: Imported types
imported CAspectFillArea;
imported CAspectMarker;
imported CAspectLine;
imported CAspectText;
imported CStructure;
---Category: Imported types
pointer CStructurePtr to CStructure from Graphic3d;
imported CStructure_Handle;
imported CLight;
---Category: Imported types
imported CPlane;
---Category: Imported types
imported CUserDraw;
---Category: Imported types
imported CView;
---Category: Imported types
imported RenderingParams;
---Purpose: Describes rendering parameters and effects.
---Category: Imported types
imported CGraduatedTrihedron;
---Category: Imported types
imported ClipPlane;
---Category: Imported types
imported ClipPlane_Handle;
imported CTexture;
imported CTransPersStruct;
imported TransModeFlags;
imported MarkerImage;
imported MarkerImage_Handle;
imported Camera_Handle;
imported transient class Volume;
primitive PtrFrameBuffer;
primitive Vec2;
primitive Vec3;
primitive Vec4;
imported Mat4;
imported Mat4d;
imported ZLayerSettings;
primitive ZLayerId;
--------------------
-- Category: Classes
--------------------
deferred class ArrayOfPrimitives;
class ArrayOfPoints;
class ArrayOfPolylines;
class ArrayOfSegments;
class ArrayOfPolygons;
class ArrayOfTriangles;
class ArrayOfTriangleStrips;
class ArrayOfTriangleFans;
class ArrayOfQuadrangles;
class ArrayOfQuadrangleStrips;
class AspectLine3d;
---Category: Classes
class AspectFillArea3d;
---Category: Classes
class AspectMarker3d;
---Category: Classes
class AspectText3d;
---Category: Classes
deferred class Group;
---Category: Classes
class MaterialAspect;
---Category: Classes
class Structure;
---Category: Classes
pointer StructurePtr to Structure from Graphic3d;
deferred class GraphicDriver;
deferred class StructureManager;
---Category: Classes
pointer StructureManagerPtr to StructureManager from Graphic3d;
deferred class DataStructureManager;
---Category: Classes
class Vector;
---Category: Classes
imported Vertex;
---Category: Classes
imported MapOfStructure;
imported SequenceOfDisplayedStructures;
---------------------------------
-- Category: Instantiated classes
---------------------------------
imported SequenceOfGroup;
class SequenceOfStructure instantiates
Sequence from TCollection
(Structure from Graphic3d);
---Category: Instantiated classes
class HSequenceOfStructure instantiates
HSequence from TCollection
(Structure from Graphic3d, SequenceOfStructure from Graphic3d);
---Category: Instantiated classes
class Array1OfVector instantiates
Array1 from TCollection (Vector from Graphic3d);
---Category: Instantiated classes
class Array1OfVertex instantiates
Array1 from TCollection (Vertex from Graphic3d);
---Category: Instantiated classes
class Array2OfVertex instantiates
Array2 from TCollection (Vertex from Graphic3d);
---Category: Instantiated classes
class ListOfShortReal instantiates
List from TCollection (ShortReal from Standard);
---Category: Instantiated classes
--ABD Integration support of system fonts (using FTGL and FreeType)
imported NListOfHAsciiString;
---Category: Instantiated classes
imported ShaderProgram_Handle;
---Category: Instantiated classes
imported SequenceOfHClipPlane;
---Category: Instantiated classes
-- Sequence of handles on clip planes
deferred class TextureRoot from Graphic3d;
deferred class TextureMap from Graphic3d;
deferred class Texture1D from Graphic3d;
deferred class Texture2D from Graphic3d;
class TextureParams from Graphic3d;
class TextureEnv from Graphic3d;
class Texture1Dmanual from Graphic3d;
class Texture1Dsegment from Graphic3d;
class Texture2Dmanual from Graphic3d;
class Texture2Dplane from Graphic3d;
enumeration ExportFormat is
EF_PostScript,
EF_EnhPostScript,
EF_TEX,
EF_PDF,
EF_SVG,
EF_PGF,
EF_EMF
end ExportFormat;
enumeration SortType is
ST_Simple, -- sorting by depth of center point of primitive(fast)
ST_BSP_Tree -- sorting by BSPTree (slow, but fine result )
end SortType;
end Graphic3d;

View File

@@ -0,0 +1,131 @@
// Created on: 2014-12-24
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_DenseVolumeData_HeaderFile
#define _Graphic3d_DenseVolumeData_HeaderFile
#include <NCollection_Array1.hxx>
#include <NCollection_Handle.hxx>
#include <Graphic3d_VolumeData.hxx>
//! Dense volumetric data of specific type
//! (stores the value in each voxel).
template<class T>
class Graphic3d_DenseVolumeData : public Graphic3d_VolumeData
{
public:
//! Type of voxel value.
typedef T DataType;
//! Type of voxel array.
typedef NCollection_Array1<DataType> VoxelArray;
public:
//! Creates uninitialized dense volumetric data.
Graphic3d_DenseVolumeData();
//! Creates dense volumetric data with the given dimensions.
Graphic3d_DenseVolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ);
//! Creates dense volumetric data with the given dimensions and data.
Graphic3d_DenseVolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ,
const NCollection_Handle<VoxelArray>& theVoxels);
//! Releases resources of dense volumetric data.
virtual ~Graphic3d_DenseVolumeData();
public:
//! Reinitializes dense volumetric data with the given dimensions.
virtual void Init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ);
//! Reinitializes dense volumetric data with the given dimensions and data.
virtual void Init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ,
const NCollection_Handle<VoxelArray>& theVoxels);
//! Returns value at the given voxel.
virtual DataType Voxel (const Standard_Integer theIndex) const
{
return myVoxels->Value (theIndex);
}
//! Returns value at the given voxel.
virtual DataType Voxel (const Standard_Integer theIndexX,
const Standard_Integer theIndexY,
const Standard_Integer theIndexZ) const
{
return myVoxels->Value (theIndexX + (theIndexY + theIndexZ * myNbVoxY) * myNbVoxX);
}
//! Sets value at the given voxel.
virtual void SetVoxel (const DataType theValue,
const Standard_Integer theIndex)
{
myVoxels->ChangeValue (theIndex) = theValue;
}
//! Sets value at the given voxel.
virtual void SetVoxel (const DataType theValue,
const Standard_Integer theIndexX,
const Standard_Integer theIndexY,
const Standard_Integer theIndexZ)
{
myVoxels->ChangeValue (theIndexX + (theIndexY + theIndexZ * myNbVoxY) * myNbVoxX) = theValue;
}
//! Returns raw voxel data.
NCollection_Handle<VoxelArray>& Data()
{
return myVoxels;
}
//! Returns raw voxel data.
const NCollection_Handle<VoxelArray>& Data() const
{
return myVoxels;
}
//! Sets raw voxel data (must correspond to dataset size).
void SetData (const NCollection_Handle<VoxelArray>& theData);
//! Checks if volumetric data is dense.
virtual Standard_Boolean IsDense() const Standard_OVERRIDE
{
return Standard_True;
}
protected:
//! Array of voxels.
NCollection_Handle<VoxelArray> myVoxels;
};
#include <Graphic3d_DenseVolumeData.lxx>
#endif // _Graphic3d_DenseVolumeData_HeaderFile

View File

@@ -0,0 +1,127 @@
// Created on: 2014-12-24
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_Assert.hxx>
//========================================================================
//Function : Graphic3d_DenseVolumeData
//Purpose :
//========================================================================
template<class T>
Graphic3d_DenseVolumeData<T>::Graphic3d_DenseVolumeData() : Graphic3d_VolumeData()
{
//
}
//========================================================================
//Function : Graphic3d_DenseVolumeData
//Purpose :
//========================================================================
template<class T>
Graphic3d_DenseVolumeData<T>::Graphic3d_DenseVolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ)
: Graphic3d_VolumeData (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ)
{
myVoxels = new VoxelArray (0, theNbVoxX * theNbVoxY * theNbVoxZ - 1);
}
//========================================================================
//Function : Graphic3d_DenseVolumeData
//Purpose :
//========================================================================
template<class T>
Graphic3d_DenseVolumeData<T>::Graphic3d_DenseVolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ,
const NCollection_Handle<VoxelArray>& theVoxels)
: Graphic3d_VolumeData (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ)
{
Standard_ASSERT_RETURN (theVoxels->Length() == theNbVoxX * theNbVoxY * theNbVoxZ,
"Error: Array size is not valid", /* none */);
myVoxels = theVoxels;
}
//========================================================================
//Function : Init
//Purpose :
//========================================================================
template<class T>
void Graphic3d_DenseVolumeData<T>::Init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ)
{
init (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ);
myVoxels = new VoxelArray (0, theNbVoxX * theNbVoxY * theNbVoxZ - 1);
}
//========================================================================
//Function : Init
//Purpose :
//========================================================================
template<class T>
void Graphic3d_DenseVolumeData<T>::Init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ,
const NCollection_Handle<VoxelArray>& theVoxels)
{
init (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ);
Standard_ASSERT_RETURN (theVoxels->Length() == theNbVoxX * theNbVoxY * theNbVoxZ,
"Error: Array size is not valid", /* none */);
myVoxels = theVoxels;
}
//========================================================================
//Function : ~Graphic3d_DenseVolumeData
//Purpose :
//========================================================================
template<class T>
Graphic3d_DenseVolumeData<T>::~Graphic3d_DenseVolumeData()
{
//
}
//========================================================================
//Function : SetData
//Purpose :
//========================================================================
template<class T>
void Graphic3d_DenseVolumeData<T>::SetData (const NCollection_Handle<VoxelArray>& theData)
{
Standard_ASSERT_RETURN (theVoxels->Length() == theNbVoxX * theNbVoxY * theNbVoxZ,
"Error: Array size is not valid", /* none */);
myVoxels = theData;
}

View File

@@ -1065,6 +1065,36 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
Update();
}
// =======================================================================
// function : AddVolume
// purpose :
// =======================================================================
void Graphic3d_Group::AddVolume (const Handle(Graphic3d_Volume)& theVolume,
const Standard_Boolean theToEvalMinMax)
{
if (IsDeleted())
{
return;
}
if (theToEvalMinMax && !theVolume->VolumeData().IsNull())
{
const BVH_Box3d& aBounds = theVolume->VolumeData()->Bounds();
myBounds.Add (BVH_Vec4f (static_cast<Standard_ShortReal> (aBounds.CornerMin().x()),
static_cast<Standard_ShortReal> (aBounds.CornerMin().y()),
static_cast<Standard_ShortReal> (aBounds.CornerMin().z()),
1.f));
myBounds.Add (BVH_Vec4f (static_cast<Standard_ShortReal> (aBounds.CornerMax().x()),
static_cast<Standard_ShortReal> (aBounds.CornerMax().y()),
static_cast<Standard_ShortReal> (aBounds.CornerMax().z()),
1.f));
}
Update();
}
// =======================================================================
// function : Marker
// purpose :

View File

@@ -0,0 +1,296 @@
// Created on: 2014-12-24
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_RgbaTransferFunction_HeaderFile
#define _Graphic3d_RgbaTransferFunction_HeaderFile
#include <NCollection_Handle.hxx>
#include <NCollection_Sequence.hxx>
#include <Graphic3d_TransferFunction.hxx>
#include <Graphic3d_TransferFunctionNode.hxx>
#include <Graphic3d_TransferFunctionLinearFilter.hxx>
#include <Graphic3d_TransferFunctionNearestFilter.hxx>
//! Defines RGBA transfer function for specific type of scalar field.
template<class PointType, class ValueType = Standard_ShortReal>
class Graphic3d_RgbaTransferFunction : public Graphic3d_TransferFunction
{
public:
//! Defines RGB color type.
typedef NCollection_Vec3<ValueType> ColorType;
//! Defines type of color node.
typedef Graphic3d_TransferFunctionNode<PointType, ColorType> ColorNode;
//! Defines type of opacity node.
typedef Graphic3d_TransferFunctionNode<PointType, ValueType> AlphaNode;
//! Defines type of color filter tool.
typedef Graphic3d_TransferFunctionFilter<PointType, ColorType> ColorFilterTool;
//! Defines type of opacity filter tool.
typedef Graphic3d_TransferFunctionFilter<PointType, ValueType> AlphaFilterTool;
public:
//! Creates empty transfer function.
Graphic3d_RgbaTransferFunction();
//! Releases resources of transfer function.
~Graphic3d_RgbaTransferFunction();
//! Saves TF to file.
Standard_Boolean SaveToFile (const Standard_Character* theFileName)
{
std::ofstream aStream;
OSD_OpenStream (aStream, theFileName, std::ios_base::binary);
if (!aStream.is_open())
{
return Standard_False;
}
const Standard_Integer aNbColorNodes = myColorNodes.Size();
const Standard_Integer aNbAlphaNodes = myAlphaNodes.Size();
aStream.write (reinterpret_cast<const Standard_Character*> (&aNbColorNodes), sizeof (Standard_Integer));
aStream.write (reinterpret_cast<const Standard_Character*> (&aNbAlphaNodes), sizeof (Standard_Integer));
for (Standard_Integer anIdx = 0; anIdx < aNbColorNodes; ++anIdx)
{
PointType aPoint = myColorNodes.Value (anIdx + 1).Point;
ValueType aR = myColorNodes.Value (anIdx + 1).Value.x();
ValueType aG = myColorNodes.Value (anIdx + 1).Value.y();
ValueType aB = myColorNodes.Value (anIdx + 1).Value.z();
aStream.write (reinterpret_cast<const Standard_Character*> (&aPoint), sizeof (PointType));
aStream.write (reinterpret_cast<const Standard_Character*> (&aR), sizeof (ValueType));
aStream.write (reinterpret_cast<const Standard_Character*> (&aG), sizeof (ValueType));
aStream.write (reinterpret_cast<const Standard_Character*> (&aB), sizeof (ValueType));
}
for (Standard_Integer anIdx = 0; anIdx < aNbAlphaNodes; ++anIdx)
{
PointType aPoint = myAlphaNodes.Value (anIdx + 1).Point;
ValueType aValue = myAlphaNodes.Value (anIdx + 1).Value;
aStream.write (reinterpret_cast<const Standard_Character*> (&aPoint), sizeof (PointType));
aStream.write (reinterpret_cast<const Standard_Character*> (&aValue), sizeof (ValueType));
}
aStream.close();
}
//! Loads TF from file.
Standard_Boolean LoadFromFile (const Standard_Character* theFileName)
{
std::ifstream aStream;
OSD_OpenStream (aStream, theFileName, std::ios_base::binary);
if (!aStream.is_open())
{
return Standard_False;
}
Standard_Integer aNbColorNodes = 0;
Standard_Integer aNbAlphaNodes = 0;
aStream.read (reinterpret_cast<Standard_Character*> (&aNbColorNodes), sizeof (Standard_Integer));
aStream.read (reinterpret_cast<Standard_Character*> (&aNbAlphaNodes), sizeof (Standard_Integer));
if (aNbColorNodes <= 0 || aNbAlphaNodes <= 0)
{
return Standard_False;
}
myColorNodes.Clear();
myAlphaNodes.Clear();
for (Standard_Integer anIdx = 0; anIdx < aNbColorNodes; ++anIdx)
{
PointType aPoint;
ValueType aR;
ValueType aG;
ValueType aB;
aStream.read (reinterpret_cast<Standard_Character*> (&aPoint), sizeof (PointType));
aStream.read (reinterpret_cast<Standard_Character*> (&aR), sizeof (ValueType));
aStream.read (reinterpret_cast<Standard_Character*> (&aG), sizeof (ValueType));
aStream.read (reinterpret_cast<Standard_Character*> (&aB), sizeof (ValueType));
AddNode (aPoint, ColorType (aR, aG, aB));
}
for (Standard_Integer anIdx = 0; anIdx < aNbAlphaNodes; ++anIdx)
{
PointType aPoint;
ValueType aValue;
aStream.read (reinterpret_cast<Standard_Character*> (&aPoint), sizeof (PointType));
aStream.read (reinterpret_cast<Standard_Character*> (&aValue), sizeof (ValueType));
AddNode (aPoint, aValue);
}
aStream.close();
Update();
}
public:
//! Appends color control point.
void AddNode (const PointType thePoint,
const ColorType& theColor)
{
myColorNodes.Append (ColorNode (thePoint, theColor));
}
//! Appends opacity control point.
void AddNode (const PointType thePoint,
const ValueType theAlpha)
{
myAlphaNodes.Append (AlphaNode (thePoint, theAlpha));
}
//! Appends color-opacity control point.
void AddNode (const PointType thePoint,
const ColorType& theColor,
const ValueType theAlpha)
{
AddNode (thePoint, theColor);
AddNode (thePoint, theAlpha);
}
//! Returns reference to the given color control point.
ColorNode& ChangeColorNodeData (const Standard_Integer theIndex)
{
return myColorNodes.ChangeValue (theIndex - 1);
}
//! Returns reference to the given opacity control point.
AlphaNode& ChangeAlphaNodeData (const Standard_Integer theIndex)
{
return myAlphaNodes.ChangeValue (theIndex - 1);
}
//! Returns const reference to the given color control point.
const ColorNode& ColorNodeData (const Standard_Integer theIndex) const
{
return myColorNodes.Value (theIndex - 1);
}
//! Returns const reference to the given opacity control point.
const AlphaNode& AlphaNodeData (const Standard_Integer theIndex) const
{
return myAlphaNodes.Value (theIndex - 1);
}
//! Removes the given color control point.
void RemoveColorNode (const Standard_Integer theIndex)
{
myColorNodes.Remove (theIndex - 1);
}
//! Removes the given opacity control point.
void RemoveAlphaNode (const Standard_Integer theIndex)
{
myAlphaNodes.Remove (theIndex - 1);
}
//! Clears all color control points.
void ClearColorNodes()
{
myColorNodes.Clear();
}
//! Clears all opacity control points.
void ClearAlphaNodes()
{
myAlphaNodes.Clear();
}
//! Returns number of color nodes.
Standard_Integer NbOfColorNodes() const
{
return myColorNodes.Size();
}
//! Returns number of opacity nodes.
Standard_Integer NbOfAlphaNodes() const
{
return myAlphaNodes.Size();
}
//! Returns color filter.
const NCollection_Handle<ColorFilterTool>& ColorFilter() const
{
return myColorFilter;
}
//! Sets color filter.
void SetColorFilter (const NCollection_Handle<ColorFilterTool>& theColorFilter)
{
myColorFilter = theColorFilter;
}
//! Returns opacity filter.
const NCollection_Handle<AlphaFilterTool>& AlphaFilter() const
{
return myAlphaFilter;
}
//! Sets opacity filter.
void SetAlphaFilter (const NCollection_Handle<AlphaFilterTool>& theAlphaFilter)
{
myAlphaFilter = theAlphaFilter;
}
public:
//! Initializes transfer function with default values.
void InitDefault (const Standard_ShortReal theScale, const Standard_Integer theNbOfNodes = 32);
//! Computes discretization table as 1D image.
virtual Handle(Image_PixMap) ImageTable (Standard_Real& theNormMinValue,
Standard_Real& theNormMaxValue,
const Standard_Integer theNumberOfRows = SIZE_OF_TABLE) const Standard_OVERRIDE;
protected:
//! List of color nodes.
NCollection_Sequence<ColorNode> myColorNodes;
//! List of opacity nodes.
NCollection_Sequence<AlphaNode> myAlphaNodes;
//! Color filter tool.
mutable NCollection_Handle<ColorFilterTool> myColorFilter;
//! Opacity filter tool.
mutable NCollection_Handle<AlphaFilterTool> myAlphaFilter;
};
#include <Graphic3d_RgbaTransferFunction.lxx>
#endif // _Graphic3d_RgbaTransferFunction_HeaderFile

View File

@@ -0,0 +1,178 @@
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <algorithm>
#include <NCollection_Vec4.hxx>
//========================================================================
//function : Graphic3d_RgbaTransferFunction
//purpose :
//========================================================================
template<typename PointType, class ValueType>
Graphic3d_RgbaTransferFunction<PointType, ValueType>::Graphic3d_RgbaTransferFunction()
: Graphic3d_TransferFunction()
{
// Set default filter -- linear
myColorFilter = new Graphic3d_TransferFunctionLinearFilter<PointType, ColorType>;
myAlphaFilter = new Graphic3d_TransferFunctionLinearFilter<PointType, ValueType>;
}
//========================================================================
//function : ~Graphic3d_RgbaTransferFunction
//purpose :
//========================================================================
template<typename PointType, class ValueType>
Graphic3d_RgbaTransferFunction<PointType, ValueType>::~Graphic3d_RgbaTransferFunction()
{
//
}
namespace Graphic3d_TransferFunctionTools
{
//! Node comparator.
template<class Node>
struct NodeComparator
{
bool operator() (const Node& theNode1, const Node& theNode2) const
{
return theNode1.Point < theNode2.Point;
}
};
//! Image constructor.
template<class T>
struct ImageConstructor
{
/* Not defined */
};
template<>
struct ImageConstructor<Standard_ShortReal>
{
static Handle(Image_PixMap) Create (const Standard_Integer theSize)
{
Handle(Image_PixMap) anImage = new Image_PixMap;
return anImage->InitZero (Image_PixMap::ImgRGBAF, theSize, 1) ? anImage : NULL;
}
};
template<>
struct ImageConstructor<unsigned char>
{
static Handle(Image_PixMap) Create (const Standard_Integer theSize)
{
Handle(Image_PixMap) anImage = new Image_PixMap;
return anImage->InitZero (Image_PixMap::ImgRGBA, theSize, 1) ? anImage : NULL;
}
};
}
namespace Graphic3d_TransferFunctionTools
{
//! Performs normalization of integral values to [0, 1] range.
template<class T>
struct ValueNormalizer
{
static Standard_Real Get (const T theValue)
{
const T aMinValue = std::numeric_limits<T>::min();
const T aMaxValue = std::numeric_limits<T>::max();
return (theValue - aMinValue) /
static_cast<Standard_Real> (aMaxValue - aMinValue);
}
};
template<>
struct ValueNormalizer<Standard_Real>
{
static Standard_Real Get (const Standard_Real theValue)
{
return theValue;
}
};
template<>
struct ValueNormalizer<Standard_ShortReal>
{
static Standard_Real Get (const Standard_ShortReal theValue)
{
return theValue;
}
};
}
//========================================================================
//function : ImageTable
//purpose :
//========================================================================
template<typename PointType, class ValueType>
Handle(Image_PixMap) Graphic3d_RgbaTransferFunction<PointType, ValueType>::ImageTable (Standard_Real& theNormMinValue,
Standard_Real& theNormMaxValue,
const Standard_Integer theNumberOfRows) const
{
if (myColorNodes.Size() < 2
|| myAlphaNodes.Size() < 2)
{
return NULL;
}
std::vector<ColorNode> aColorNodes (myColorNodes.begin(), myColorNodes.end());
std::vector<AlphaNode> aAlphaNodes (myAlphaNodes.begin(), myAlphaNodes.end());
std::sort (aColorNodes.begin(), aColorNodes.end(),
Graphic3d_TransferFunctionTools::NodeComparator<ColorNode>());
std::sort (aAlphaNodes.begin(), aAlphaNodes.end(),
Graphic3d_TransferFunctionTools::NodeComparator<AlphaNode>());
Handle(Image_PixMap) aImageTable =
Graphic3d_TransferFunctionTools::ImageConstructor<ValueType>::Create (theNumberOfRows);
if (aImageTable.IsNull())
{
return NULL;
}
const PointType aMinValue = std::min (aColorNodes.front().Point,
aAlphaNodes.front().Point);
const PointType aMaxValue = std::max (aColorNodes.back().Point,
aAlphaNodes.back().Point);
theNormMinValue = Graphic3d_TransferFunctionTools::ValueNormalizer<PointType>::Get (aMinValue);
theNormMaxValue = Graphic3d_TransferFunctionTools::ValueNormalizer<PointType>::Get (aMaxValue);
myColorFilter->Init (&aColorNodes.front(), myColorNodes.Size());
myAlphaFilter->Init (&aAlphaNodes.front(), myAlphaNodes.Size());
Standard_Real aStep = (aMaxValue - aMinValue) / static_cast<Standard_Real> (theNumberOfRows - 1);
for (Standard_Integer anIndex = 0; anIndex < theNumberOfRows; ++anIndex)
{
const PointType aPoint = static_cast<PointType> (aMinValue + aStep * anIndex);
const ColorType aColor = myColorFilter->Value (aPoint);
const ValueType aAlpha = myAlphaFilter->Value (aPoint);
NCollection_Vec4<ValueType>& aPixel = aImageTable->ChangeValue<NCollection_Vec4<ValueType> > (0, anIndex);
aPixel = NCollection_Vec4<ValueType> (
aColor.x(), aColor.y(), aColor.z(), aAlpha);
}
return aImageTable;
}

View File

@@ -1,6 +1,6 @@
// Created on: 2008-09-01
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -13,20 +13,7 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Graphic3d_TransferFunction.hxx>
#include <Voxel_SplitData.hxx>
Voxel_SplitData::Voxel_SplitData():myValues(0),mySplitData(0)
{
}
Standard_Address& Voxel_SplitData::GetValues()
{
return myValues;
}
Standard_Address& Voxel_SplitData::GetSplitData()
{
return mySplitData;
}
IMPLEMENT_STANDARD_HANDLE (Graphic3d_TransferFunction, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TransferFunction, Standard_Transient)

View File

@@ -0,0 +1,74 @@
// Created on: 2015-01-26
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_TransferFunction_HeaderFile
#define _Graphic3d_TransferFunction_HeaderFile
#include <Image_PixMap.hxx>
//! Defines abstract transfer function that maps values
//! of scalar field to specific RGB color and opacity.
class Graphic3d_TransferFunction : public Standard_Transient
{
public:
//! Default size of discretization table.
static const Standard_Integer SIZE_OF_TABLE = 512;
public:
//! Creates empty transfer function.
Graphic3d_TransferFunction() : myState (1)
{
//
}
//! Releases resources of transfer function.
virtual ~Graphic3d_TransferFunction()
{
//
}
//! Returns current state of transfer function.
Standard_Size State() const
{
return myState;
}
//! Updates current state of transfer function.
void Update()
{
++myState;
}
//! Computes discretization table as 1D image.
virtual Handle(Image_PixMap) ImageTable (Standard_Real& theNormMinValue,
Standard_Real& theNormMaxValue,
const Standard_Integer theNumberOfRows = SIZE_OF_TABLE) const = 0;
protected:
//! Current state of transfer function.
Standard_Size myState;
public:
DEFINE_STANDARD_RTTI (Graphic3d_TransferFunction)
};
DEFINE_STANDARD_HANDLE (Graphic3d_TransferFunction, Standard_Transient)
#endif // _Graphic3d_TransferFunction_HeaderFile

View File

@@ -0,0 +1,52 @@
// Created on: 2014-12-25
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_TransferFunctionFilter_HeaderFile
#define _Graphic3d_TransferFunctionFilter_HeaderFile
#include <Graphic3d_TransferFunctionNode.hxx>
//! Transfer function filter used for generating discretization table.
template<typename PointType, typename ValueType>
class Graphic3d_TransferFunctionFilter
{
public:
//! Type of control point.
typedef Graphic3d_TransferFunctionNode<PointType, ValueType> Node;
public:
//! Initializes internal structures.
virtual void Init (const Node* theNodes,
const Standard_Integer theCount)
{
myNodes = theNodes;
myCount = theCount;
}
//! Returns interpolated value at the given point.
virtual ValueType Value (const PointType thePoint) const = 0;
protected:
//! Array of control points.
const Node* myNodes;
//! Total number of control points.
Standard_Integer myCount;
};
#endif // _Graphic3d_TransferFunctionFilter_HeaderFile

View File

@@ -0,0 +1,33 @@
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_TransferFunctionLinearFilter_HeaderFile
#define _Graphic3d_TransferFunctionLinearFilter_HeaderFile
#include <Graphic3d_TransferFunctionFilter.hxx>
//! Linear filter used for generating discretization table.
template<typename PointType, typename ValueType>
class Graphic3d_TransferFunctionLinearFilter : public Graphic3d_TransferFunctionFilter<PointType, ValueType>
{
public:
//! Returns interpolated value at the given point.
virtual ValueType Value (const PointType thePoint) const Standard_OVERRIDE;
};
#include <Graphic3d_TransferFunctionLinearFilter.lxx>
#endif // _Graphic3d_TransferFunctionLinearFilter_HeaderFile

View File

@@ -0,0 +1,70 @@
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_Assert.hxx>
#include <NCollection_Vec3.hxx>
namespace Graphic3d_TransferFunctionTools
{
template<typename T>
struct Mix
{
static T Get (const T theVal1,
const T theVal2,
const Standard_Real theAlpha)
{
return static_cast<T> (theVal1 * (1.0 - theAlpha) + theVal2 * theAlpha);
}
static NCollection_Vec3<T> Get (const NCollection_Vec3<T>& theVal1,
const NCollection_Vec3<T>& theVal2,
const Standard_Real theAlpha)
{
return NCollection_Vec3<T> (Get (theVal1.x(), theVal2.x(), theAlpha),
Get (theVal1.y(), theVal2.y(), theAlpha),
Get (theVal1.z(), theVal2.z(), theAlpha));
}
};
}
//========================================================================
//function : Value
//purpose :
//========================================================================
template<typename PointType, typename ValueType>
ValueType Graphic3d_TransferFunctionLinearFilter<PointType, ValueType>::Value (const PointType thePoint) const
{
Standard_ASSERT_RAISE (myCount > 1,
"Error! Transfer function must contain a least 2 control points");
if (thePoint <= myNodes[0].Point)
{
return myNodes[0].Value;
}
for (Standard_Integer anIndex = 1; anIndex < myCount; ++anIndex)
{
if (thePoint < myNodes[anIndex].Point)
{
const Node& aLft = myNodes[anIndex - 1];
const Node& aRgh = myNodes[anIndex ];
return Graphic3d_TransferFunctionTools::Mix<ValueType>::Get (
aLft.Value, aRgh.Value, (thePoint - aLft.Point) / static_cast<Standard_Real> (aRgh.Point - aLft.Point));
}
}
return myNodes[myCount - 1].Value;
}

View File

@@ -0,0 +1,33 @@
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_TransferFunctionNearestFilter_HeaderFile
#define _Graphic3d_TransferFunctionNearestFilter_HeaderFile
#include <Graphic3d_TransferFunctionFilter.hxx>
//! Nearest filter used for generating discretization table.
template<typename PointType, typename ValueType>
class Graphic3d_TransferFunctionNearestFilter : public Graphic3d_TransferFunctionFilter<PointType, ValueType>
{
public:
//! Returns nearest value at the given point.
virtual ValueType Value (const PointType thePoint) const Standard_OVERRIDE;
};
#include <Graphic3d_TransferFunctionNearestFilter.lxx>
#endif // _Graphic3d_TransferFunctionNearestFilter_HeaderFile

View File

@@ -0,0 +1,70 @@
// Created on: 2015-01-28
// Created by: Denis BOGOLEPOV
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_Assert.hxx>
#include <NCollection_Vec3.hxx>
namespace Graphic3d_TransferFunctionTools
{
template<class PointType, class ValueType>
struct Nearest
{
static ValueType Get (const Graphic3d_TransferFunctionNode<PointType, ValueType>& theNode1,
const Graphic3d_TransferFunctionNode<PointType, ValueType>& theNode2,
const PointType& thePoint)
{
const PointType aHalfDistance = (theNode2.Point - theNode1.Point) / static_cast<PointType>(2);
if ( (thePoint - theNode1.Point) < aHalfDistance)
{
return theNode1.Value;
}
else
{
return theNode2.Value;
}
}
};
}
//========================================================================
//function : Value
//purpose :
//========================================================================
template<typename PointType, typename ValueType>
ValueType Graphic3d_TransferFunctionNearestFilter<PointType, ValueType>::Value (const PointType thePoint) const
{
Standard_ASSERT_RAISE (myCount > 1,
"Error! Transfer function must contain a least 2 control points");
if (thePoint <= myNodes[0].Point)
{
return myNodes[0].Value;
}
else
{
for (Standard_Integer anIndex = 1; anIndex < myCount; ++anIndex)
{
const Node& aLeft = myNodes[anIndex - 1];
const Node& aRight = myNodes[anIndex ];
if (thePoint <= aRight.Point)
{
return Graphic3d_TransferFunctionTools::Nearest<PointType, ValueType>::Get (aLeft, aRight, thePoint);
}
}
return myNodes[myCount - 1].Value;
}
}

View File

@@ -0,0 +1,47 @@
// Created on: 2014-12-25
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_TransferFunctionNode_HeaderFile
#define _Graphic3d_TransferFunctionNode_HeaderFile
#include <Graphic3d_Vec.hxx>
//! Describes control point (knot) of the transfer function.
template<class PointType, class ValueType>
struct Graphic3d_TransferFunctionNode
{
//! Position of control point.
PointType Point;
//! Property at the control point.
ValueType Value;
//! Creates unitialized control point.
Graphic3d_TransferFunctionNode()
{
//
}
//! Creates new control point.
Graphic3d_TransferFunctionNode (const PointType thePoint,
const ValueType theValue)
: Point (thePoint),
Value (theValue)
{
//
}
};
#endif // _Graphic3d_TransferFunctionNode_HeaderFile

View File

@@ -0,0 +1,73 @@
// Created on: 2014-12-12
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Graphic3d_Volume.hxx>
#include <Graphic3d_ShaderObject.hxx>
IMPLEMENT_STANDARD_HANDLE (Graphic3d_Volume, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Volume, Standard_Transient)
//=================================================
//function : Graphic3d_Volume
//purpose :
//=================================================
Graphic3d_Volume::Graphic3d_Volume()
: myNumOfSamples (1000),
myOpacityScale (1.0f),
myApplyShading (Standard_False),
myTriCubFilter (Standard_False),
myTraceShadows (Standard_False),
myRandomShift (Standard_False)
{
Init();
}
//=================================================
//function : ~Graphic3d_Volume
//purpose :
//=================================================
Graphic3d_Volume::~Graphic3d_Volume()
{
//
}
//=================================================
//function : Init
//purpose :
//=================================================
Standard_Boolean Graphic3d_Volume::Init()
{
if (myShaderProgram.IsNull())
{
myShaderProgram = new Graphic3d_ShaderProgram();
}
const TCollection_AsciiString& aShaderFolder = Graphic3d_ShaderProgram::ShadersFolder();
if (!myShaderProgram->AttachShader (Graphic3d_ShaderObject::
CreateFromFile (Graphic3d_TOS_VERTEX, aShaderFolder + "/VolumeRender.vs")))
{
return Standard_False;
}
if (!myShaderProgram->AttachShader (Graphic3d_ShaderObject::
CreateFromFile (Graphic3d_TOS_FRAGMENT, aShaderFolder + "/VolumeRender.fs")))
{
return Standard_False;
}
return Standard_True;
}

View File

@@ -0,0 +1,239 @@
// Created on: 2014-12-12
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_Volume_HeaderFile
#define _Graphic3d_Volume_HeaderFile
#include <Graphic3d_VolumeData.hxx>
#include <Graphic3d_ShaderProgram.hxx>
#include <Graphic3d_TransferFunction.hxx>
//! Contains definition of 3D volume object.
class Graphic3d_Volume : public Standard_Transient
{
public:
//! Creates uninitialized volume object.
Standard_EXPORT Graphic3d_Volume();
//! Release resources of volume object.
Standard_EXPORT virtual ~Graphic3d_Volume();
public:
//! Returns volumetric data attached to the volume.
const Handle(Graphic3d_VolumeData)& VolumeData() const
{
return myVolumeData;
}
//! Attaches the given volumetric data to the volume.
void AttachVolumeData (const Handle(Graphic3d_VolumeData)& theData)
{
myVolumeData = theData;
}
//! Returns transfer function attached to the volume.
const Handle(Graphic3d_TransferFunction)& TransferFunction() const
{
return myTransFunction;
}
//! Attaches the given transfer function to the volume.
void AttachTransferFunction (const Handle(Graphic3d_TransferFunction)& theTransFunc)
{
myTransFunction = theTransFunc;
}
//! Returns maximum number of samples per ray.
Standard_Integer NumOfSamples() const
{
return myNumOfSamples;
}
//! Sets maximum number of samples per ray.
void SetNumOfSamples (const Standard_Integer theNbOfSamples)
{
myNumOfSamples = theNbOfSamples;
}
//! Returns scaling factor for volume opacity.
Standard_ShortReal OpacityScale() const
{
return myOpacityScale;
}
//! Sets scaling factor for volume opacity.
void SetOpacityScale (const Standard_ShortReal theOpacityScale)
{
myOpacityScale = theOpacityScale;
}
//! Checks if tri-cubic volume filtering is enabled.
Standard_Boolean TriCubFilter() const
{
return myTriCubFilter;
}
//! Enables/disables tri-cubic volume filtering.
void SetTriCubFilter (const Standard_Boolean theIsEnabled)
{
myTriCubFilter = theIsEnabled;
}
//! Checks if volume shading is enabled.
Standard_Boolean ApplyShading() const
{
return myApplyShading;
}
//! Enables/disables volume shading.
void SetApplyShading (const Standard_Boolean theIsEnabled)
{
myApplyShading = theIsEnabled;
}
//! Checks if tracing of shadow rays is enabled.
Standard_Boolean TraceShadows() const
{
return myTraceShadows;
}
//! Enables/disables tracing of shadow rays.
void SetTraceShadows (const Standard_Boolean theIsEnabled)
{
myTraceShadows = theIsEnabled;
}
//! Checks if random shift of rays is enabled.
Standard_Boolean RandomShift() const
{
return myRandomShift;
}
//! Enables/disables random shift of rays.
void SetRandomShift (const Standard_Boolean theIsEnabled)
{
myRandomShift = theIsEnabled;
}
//! Checks if iso-surface rendering is enabled.
Standard_Boolean IsoSurfaceMode() const
{
return myIsoSurfaceMode;
}
//! Enables/disables iso-surface rendering.
void SetIsoSurfaceMode (const Standard_Boolean theIsEnabled)
{
myIsoSurfaceMode = theIsEnabled;
}
//! Checks if 2D slice rendering is enabled.
Standard_Boolean SliceMode() const
{
return mySliceMode;
}
//! Enables/disables 2D slice rendering.
void SetSliceMode (const Standard_Boolean theIsEnabled)
{
mySliceMode = theIsEnabled;
}
//! Normalized [0, 1].
Standard_ShortReal IsoSurfaceLevel() const
{
return myIsoSurfaceLevel;
}
//! Normalized [0, 1].
void SetIsoSurfaceLevel (const Standard_ShortReal theValue)
{
myIsoSurfaceLevel = theValue;
}
//! Normalized [0, 1].
Standard_ShortReal SliceLevel() const
{
return mySliceLevel;
}
//! Normalized [0, 1].
void SetSliceLevel (const Standard_ShortReal theValue)
{
mySliceLevel = theValue;
}
//! Returns shader program used for volume visualization.
Handle(Graphic3d_ShaderProgram) ShaderProgram()
{
return myShaderProgram;
}
protected:
//! Initializes volume rendering options.
Standard_EXPORT virtual Standard_Boolean Init();
protected:
//! Maximum number of samples per ray.
Standard_Integer myNumOfSamples;
//! Scaling factor for volume opacity.
Standard_ShortReal myOpacityScale;
//! Enables/disables volume shading.
Standard_Boolean myApplyShading;
//! Enables/disables tri-cubic filtering.
Standard_Boolean myTriCubFilter;
//! Enables/disables tracing of shadow rays.
Standard_Boolean myTraceShadows;
//! Enables/disables random shift of rays.
Standard_Boolean myRandomShift;
//! Enables/disables iso-surface rendering.
Standard_Boolean myIsoSurfaceMode;
//! Enables/disables 2D slice rendering.
Standard_Boolean mySliceMode;
Standard_ShortReal myIsoSurfaceLevel;
Standard_ShortReal mySliceLevel;
protected:
// Volumetric data for visualization.
Handle(Graphic3d_VolumeData) myVolumeData;
//! Shader program used for volume visualization.
Handle(Graphic3d_ShaderProgram) myShaderProgram;
//! Transfer function used for colorizing volume.
Handle(Graphic3d_TransferFunction) myTransFunction;
public:
DEFINE_STANDARD_RTTI (Graphic3d_Volume)
};
DEFINE_STANDARD_HANDLE (Graphic3d_Volume, Standard_Transient)
#endif // _Graphic3d_Volume_HeaderFile

View File

@@ -0,0 +1,78 @@
// Created on: 2014-12-24
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Graphic3d_VolumeData.hxx>
IMPLEMENT_STANDARD_HANDLE (Graphic3d_VolumeData, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_VolumeData, Standard_Transient)
//========================================================================
//function : Graphic3d_VolumeData
//purpose :
//========================================================================
Graphic3d_VolumeData::Graphic3d_VolumeData()
: myNbVoxX (1),
myNbVoxY (1),
myNbVoxZ (1),
myState (1)
{
//
}
//========================================================================
//function : Graphic3d_VolumeData
//purpose :
//========================================================================
Graphic3d_VolumeData::Graphic3d_VolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ)
: myState (1)
{
init (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ);
}
//========================================================================
//function : ~Graphic3d_VolumeData
//purpose :
//========================================================================
Graphic3d_VolumeData::~Graphic3d_VolumeData()
{
//
}
//========================================================================
//function : init
//purpose :
//========================================================================
void Graphic3d_VolumeData::init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ)
{
myBounds = theBounds;
myNbVoxX = theNbVoxX;
myNbVoxY = theNbVoxY;
myNbVoxZ = theNbVoxZ;
myVoxSize = myBounds.Size() * Graphic3d_Vec3d (
1.0 / static_cast<Standard_Real> (theNbVoxX),
1.0 / static_cast<Standard_Real> (theNbVoxY),
1.0 / static_cast<Standard_Real> (theNbVoxZ));
}

View File

@@ -0,0 +1,147 @@
// Created on: 2014-12-24
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Graphic3d_VolumeData_HeaderFile
#define _Graphic3d_VolumeData_HeaderFile
#include <BVH_Box.hxx>
#include <Graphic3d_Vec3.hxx>
//! Base class for voxel-based volumetric data.
class Graphic3d_VolumeData : public Standard_Transient
{
public:
//! Creates empty volumetric data.
Standard_EXPORT Graphic3d_VolumeData();
//! Creates volumetric data with the given dimensions.
Standard_EXPORT Graphic3d_VolumeData (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ);
//! Release resources of volumetric data.
Standard_EXPORT virtual ~Graphic3d_VolumeData();
public:
//! Returns bounding box of volumetric data.
const BVH_Box3d& Bounds() const
{
return myBounds;
}
//! Sets bounding box of volumetric data.
void SetBounds (const BVH_Box3d& theBounds)
{
myBounds = theBounds;
}
//! Returns number of voxels in X dimension.
Standard_Integer NbVoxelX() const
{
return myNbVoxX;
}
//! Returns number of voxels in Y dimension.
Standard_Integer NbVoxelY() const
{
return myNbVoxY;
}
//! Returns number of voxels in Z dimension.
Standard_Integer NbVoxelZ() const
{
return myNbVoxZ;
}
//! Returns center of the given voxel.
Graphic3d_Vec3d VoxelCenter (const Standard_Integer theIndexX,
const Standard_Integer theIndexY,
const Standard_Integer theIndexZ) const
{
return myBounds.CornerMin() + myVoxSize *
Graphic3d_Vec3d (static_cast<Standard_Real> (theIndexX + 0.5),
static_cast<Standard_Real> (theIndexY + 0.5),
static_cast<Standard_Real> (theIndexZ + 0.5));
}
//! Returns origin (minimum corner) of the given voxel.
Graphic3d_Vec3d VoxelOrigin (const Standard_Integer theIndexX,
const Standard_Integer theIndexY,
const Standard_Integer theIndexZ) const
{
return myBounds.CornerMin() + myVoxSize *
Graphic3d_Vec3d (static_cast<Standard_Real> (theIndexX),
static_cast<Standard_Real> (theIndexY),
static_cast<Standard_Real> (theIndexZ));
}
//! Checks if volumetric data is dense.
virtual Standard_Boolean IsDense() const
{
return Standard_False;
}
//! Returns current state of volumetric data (must be updated by application).
Standard_Size State() const
{
return myState;
}
//! Updates current state of volumetric data (affects the rendering).
void Update()
{
++myState;
}
protected:
//! Reinitializes volumetric data.
Standard_EXPORT virtual void init (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ);
protected:
//! Bounding box of volumetric data.
BVH_Box3d myBounds;
//! Number of voxels in X dimension.
Standard_Integer myNbVoxX;
//! Number of voxels in Y dimension.
Standard_Integer myNbVoxY;
//! Number of voxels in Z dimension.
Standard_Integer myNbVoxZ;
//! Size of single voxel (grid step).
Graphic3d_Vec3d myVoxSize;
private:
//! Current state of the data.
Standard_Size myState;
public:
DEFINE_STANDARD_RTTI (Graphic3d_VolumeData)
};
DEFINE_STANDARD_HANDLE (Graphic3d_VolumeData, Standard_Transient)
#endif // _Graphic3d_VolumeData_HeaderFile

View File

@@ -327,6 +327,15 @@ public:
return aCopy;
}
//! Convert the vector.
template<class T>
NCollection_Vec3<T> Convert() const
{
return NCollection_Vec3<T> (static_cast<T> (v[0]),
static_cast<T> (v[1]),
static_cast<T> (v[2]));
}
//! Computes the cross product.
static NCollection_Vec3 Cross (const NCollection_Vec3& theVec1,
const NCollection_Vec3& theVec2)

View File

@@ -153,5 +153,26 @@ OpenGl_VertexBufferCompat.cxx
OpenGl_VertexBufferCompat.hxx
OpenGl_VertexBufferEditor.hxx
OpenGl_View_Raytrace.cxx
OpenGl_TextBuilder.hxx
OpenGl_TextBuilder.cxx
OpenGl_Flipper.hxx
OpenGl_Flipper.cxx
OpenGl_BVHTreeSelector.hxx
OpenGl_BVHTreeSelector.cxx
OpenGl_BVHClipPrimitiveSet.cxx
OpenGl_BVHClipPrimitiveSet.hxx
OpenGl_ArbTexBindless.hxx
Handle_OpenGl_Sampler.hxx
OpenGl_Sampler.hxx
OpenGl_Sampler.cxx
OpenGl_Utils.hxx
OpenGl_Quadric.hxx
OpenGl_Quadric.cxx
OpenGl_Cylinder.hxx
OpenGl_Cylinder.cxx
OpenGl_Disk.hxx
OpenGl_Disk.cxx
OpenGl_Sphere.hxx
OpenGl_Sphere.cxx
OpenGl_BackgroundArray.hxx
OpenGl_BackgroundArray.cxx
OpenGl_Volume.hxx
OpenGl_Volume.cxx

View File

@@ -22,6 +22,7 @@
#include <OpenGl_Structure.hxx>
#include <OpenGl_Text.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_Volume.hxx>
#include <Graphic3d_ArrayOfPrimitives.hxx>
#include <Graphic3d_CUserDraw.hxx>
@@ -200,6 +201,23 @@ void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theTy
Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
}
// =======================================================================
// function : AddVolume
// purpose :
// =======================================================================
void OpenGl_Group::AddVolume (const Handle(Graphic3d_Volume)& theVolume,
const Standard_Boolean theToEvalMinMax)
{
if (IsDeleted())
{
return;
}
AddElement (new OpenGl_Volume (theVolume));
Graphic3d_Group::AddVolume (theVolume, theToEvalMinMax);
}
// =======================================================================
// function : Text
// purpose :

View File

@@ -19,6 +19,7 @@
#include <InterfaceGraphic_Graphic3d.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_Structure.hxx>
#include <Graphic3d_Volume.hxx>
#include <NCollection_List.hxx>
#include <OpenGl_AspectLine.hxx>
@@ -67,6 +68,10 @@ public:
const Handle(Graphic3d_BoundBuffer)& theBounds,
const Standard_Boolean theToEvalMinMax);
//! Add a volume data for display
Standard_EXPORT virtual void AddVolume (const Handle(Graphic3d_Volume)& theVolume,
const Standard_Boolean theToEvalMinMax = Standard_True);
//! Add text element
Standard_EXPORT virtual void Text (const Standard_CString theTextUtf,
const Graphic3d_Vertex& thePoint,

View File

@@ -747,3 +747,94 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
return false;
#endif
}
// =======================================================================
// function : Init3D
// purpose :
// =======================================================================
bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Standard_Integer theSizeZ,
const OpenGl_TextureFormat& theFormat,
const void* thePixels)
{
if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (1, 2))
{
return false;
}
myTarget = GL_TEXTURE_3D;
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ);
Bind (theCtx);
if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
{
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
else
{
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
//const GLint anIntFormat = theFormat.Internal();
//myTextFormat = theFormat.Format();
theCtx->core15->glTexImage3D (GL_PROXY_TEXTURE_3D,
0,
theFormat.Internal(),
aSizeX,
aSizeY,
aSizeZ,
0,
theFormat.Format(),
theFormat.DataType(),
NULL);
GLint aTestSizeX = 0;
GLint aTestSizeY = 0;
GLint aTestSizeZ = 0;
glGetTexLevelParameteriv (
GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
glGetTexLevelParameteriv (
GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
glGetTexLevelParameteriv (
GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ);
if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
{
Unbind (theCtx);
return false;
}
theCtx->core15->glTexImage3D (GL_TEXTURE_3D,
0,
theFormat.Internal(),
aSizeX,
aSizeY,
aSizeZ,
0,
theFormat.Format(),
theFormat.DataType(),
thePixels);
if (glGetError() != GL_NO_ERROR)
{
Unbind (theCtx);
return false;
}
mySizeX = aSizeX;
mySizeY = aSizeY;
mySizeZ = aSizeZ;
Unbind (theCtx);
return true;
}

View File

@@ -49,6 +49,11 @@ struct OpenGl_TextureFormatSelector<GLubyte>
return GL_NONE;
}
}
static GLint DataType()
{
return GL_UNSIGNED_BYTE;
}
};
template<>
@@ -70,6 +75,11 @@ struct OpenGl_TextureFormatSelector<GLushort>
return GL_NONE;
}
}
static GLint DataType()
{
return GL_UNSIGNED_SHORT;
}
};
template<>
@@ -91,6 +101,11 @@ struct OpenGl_TextureFormatSelector<GLfloat>
return GL_NONE;
}
}
static GLint DataType()
{
return GL_FLOAT;
}
};
//! Stores parameters of OpenGL texture format.
@@ -124,25 +139,36 @@ public:
return myInternal;
}
//! Returns OpenGL data type of the pixel data.
inline GLint DataType() const
{
return myDataType;
}
//! Returns texture format for specified type and number of channels.
template<class T, int N>
static OpenGl_TextureFormat Create()
{
return OpenGl_TextureFormat (N, OpenGl_TextureFormatSelector<T>::Internal (N));
return OpenGl_TextureFormat (N,
OpenGl_TextureFormatSelector<T>::Internal (N),
OpenGl_TextureFormatSelector<T>::DataType ());
}
private:
//! Creates new texture format.
OpenGl_TextureFormat (const GLint theChannels,
const GLint theInternal)
const GLint theInternal,
const GLint theDataType)
: myInternal (theInternal),
myChannels (theChannels) {}
myChannels (theChannels),
myDataType (theDataType) {}
private:
GLint myInternal; //!< OpenGL internal format of the pixel data
GLint myChannels; //!< Number of channels for each pixel (from 1 to 4)
GLint myDataType; //!< OpenGL data type of input pixel data
};
@@ -254,6 +280,14 @@ public:
const Standard_Integer theSizeY,
const OpenGl_TextureFormat& theFormat);
//! Initializes 3D texture rectangle with specified format and size.
Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx,
const Standard_Integer theSizeX,
const Standard_Integer theSizeY,
const Standard_Integer theSizeZ,
const OpenGl_TextureFormat& theFormat,
const void* thePixels);
//! @return true if texture was generated within mipmaps
Standard_EXPORT const Standard_Boolean HasMipmaps() const;
@@ -276,6 +310,7 @@ protected:
GLenum myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D
GLsizei mySizeX; //!< texture width
GLsizei mySizeY; //!< texture height
GLsizei mySizeZ; //!< texture depth
GLenum myTextFormat; //!< texture format - GL_RGB, GL_RGBA,...
Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
bool myIsAlpha; //!< indicates alpha format

View File

@@ -0,0 +1,520 @@
// Created on: 2014-12-10
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OpenGl_View.hxx>
#include <OpenGl_Volume.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <Graphic3d_DenseVolumeData.hxx>
#include <Graphic3d_RgbaTransferFunction.hxx>
// Use this macro to output debug info
#define VOLUME_RENDER_PRINT_INFO
// =======================================================================
// function : OpenGl_Volume
// purpose :
// =======================================================================
OpenGl_Volume::OpenGl_Volume (const Handle(Graphic3d_Volume)& theVolume)
: OpenGl_Element()
{
// Set invalid states
myVolumeDataState = 0;
myTransFunctState = 0;
Standard_ASSERT_RAISE (!theVolume.IsNull(),
"Error: Graphic 3D volume object is NULL!");
myVolumeSource = theVolume;
srand (static_cast<unsigned int> (time (NULL)));
}
// =======================================================================
// function : ~OpenGl_Volume
// purpose :
// =======================================================================
OpenGl_Volume::~OpenGl_Volume()
{
//
}
// =======================================================================
// function : Release
// purpose :
// =======================================================================
void OpenGl_Volume::Release (OpenGl_Context* theContext)
{
if (!myVolumeDataTex.IsNull())
{
myVolumeDataTex->Release (theContext);
}
if (!myTransFunctTex.IsNull())
{
myTransFunctTex->Release (theContext);
}
if (myDummyQuad.IsValid())
{
myDummyQuad.Release (theContext);
}
}
// =======================================================================
// function : BuildProgram
// purpose :
// =======================================================================
Standard_Boolean OpenGl_Volume::BuildProgram (const Handle(OpenGl_Context)& theContext) const
{
if (myIsProgramReady)
{
return Standard_True;
}
myIsProgramReady = Standard_True;
if (myVolumeProgGL.IsNull())
{
TCollection_AsciiString aKey;
myIsProgramReady &= theContext->ShaderManager()->Create (
myVolumeSource->ShaderProgram(), aKey, myVolumeProgGL);
}
if (myIsProgramReady)
{
GetUniformLocations (theContext);
}
const GLfloat aVertices[] = { -1.f, -1.f, 0.f,
-1.f, 1.f, 0.f,
1.f, 1.f, 0.f,
1.f, 1.f, 0.f,
1.f, -1.f, 0.f,
-1.f, -1.f, 0.f };
myDummyQuad.Init (theContext, 3, 6, aVertices);
return myIsProgramReady = Standard_True;
}
// =======================================================================
// function : GetUniformLocations
// purpose :
// =======================================================================
void OpenGl_Volume::GetUniformLocations (const Handle(OpenGl_Context)& theContext) const
{
theContext->BindProgram (myVolumeProgGL);
myLocation.CameraOriginLT = myVolumeProgGL->GetUniformLocation (theContext, "uOriginLT");
myLocation.CameraOriginLB = myVolumeProgGL->GetUniformLocation (theContext, "uOriginLB");
myLocation.CameraOriginRT = myVolumeProgGL->GetUniformLocation (theContext, "uOriginRT");
myLocation.CameraOriginRB = myVolumeProgGL->GetUniformLocation (theContext, "uOriginRB");
myLocation.CameraDirectLT = myVolumeProgGL->GetUniformLocation (theContext, "uDirectLT");
myLocation.CameraDirectLB = myVolumeProgGL->GetUniformLocation (theContext, "uDirectLB");
myLocation.CameraDirectRT = myVolumeProgGL->GetUniformLocation (theContext, "uDirectRT");
myLocation.CameraDirectRB = myVolumeProgGL->GetUniformLocation (theContext, "uDirectRB");
myLocation.NumOfSamples = myVolumeProgGL->GetUniformLocation (theContext, "uNumOfSamples");
myLocation.TriCubFilter = myVolumeProgGL->GetUniformLocation (theContext, "uTriCubFilter");
myLocation.ApplyShading = myVolumeProgGL->GetUniformLocation (theContext, "uApplyShading");
myLocation.TraceShadows = myVolumeProgGL->GetUniformLocation (theContext, "uTraceShadows");
myLocation.RandomShift = myVolumeProgGL->GetUniformLocation (theContext, "uRandomShift");
myLocation.VolTexelSize = myVolumeProgGL->GetUniformLocation (theContext, "uVolTexelSize");
myLocation.NormMinValue = myVolumeProgGL->GetUniformLocation (theContext, "uNormMinValue");
myLocation.NormMaxValue = myVolumeProgGL->GetUniformLocation (theContext, "uNormMaxValue");
myLocation.OpacityScale = myVolumeProgGL->GetUniformLocation (theContext, "uOpacityScale");
myLocation.BoxCornerMin = myVolumeProgGL->GetUniformLocation (theContext, "uBoxCornerMin");
myLocation.BoxCornerMax = myVolumeProgGL->GetUniformLocation (theContext, "uBoxCornerMax");
myLocation.TransferFunct = myVolumeProgGL->GetUniformLocation (theContext, "uTransferFunct");
myLocation.VolumeTexture = myVolumeProgGL->GetUniformLocation (theContext, "uVolumeTexture");
myLocation.RandomSeed = myVolumeProgGL->GetUniformLocation (theContext, "uRandomSeed");
myLocation.IsoSurfaceMode = myVolumeProgGL->GetUniformLocation (theContext, "uIsoSurfaceMode");
myLocation.TraceSliceMode = myVolumeProgGL->GetUniformLocation (theContext, "uTraceSliceMode");
myLocation.IsoSurfaceLevel = myVolumeProgGL->GetUniformLocation (theContext, "uIsoSurfaceLevel");
myLocation.TraceSliceLevel = myVolumeProgGL->GetUniformLocation (theContext, "uTraceSliceLevel");
}
// =======================================================================
// function : SetUniformValues
// purpose :
// =======================================================================
void OpenGl_Volume::SetUniformValues (const Handle(OpenGl_Context)& theContext,
const OpenGl_Vec3* theOrigins,
const OpenGl_Vec3* theDirects) const
{
// Update state of volume and transfer function textures
if (!UpdateTextures (theContext))
{
return;
}
const Handle(Graphic3d_VolumeData)& aVolumeData = myVolumeSource->VolumeData();
// Set bounding box
myVolumeProgGL->SetUniform (theContext,
myLocation.BoxCornerMin, aVolumeData->Bounds().CornerMin().Convert<GLfloat>());
myVolumeProgGL->SetUniform (theContext,
myLocation.BoxCornerMax, aVolumeData->Bounds().CornerMax().Convert<GLfloat>());
// Set texture samplers
myVolumeProgGL->SetUniform (theContext, myLocation.VolumeTexture, 0);
myVolumeProgGL->SetUniform (theContext, myLocation.TransferFunct, 1);
// Set rendering options
myVolumeProgGL->SetUniform (theContext, myLocation.NumOfSamples, myVolumeSource->NumOfSamples());
myVolumeProgGL->SetUniform (theContext, myLocation.OpacityScale, myVolumeSource->OpacityScale());
myVolumeProgGL->SetUniform (theContext, myLocation.NormMinValue, static_cast<Standard_ShortReal> (myNormMinValue));
myVolumeProgGL->SetUniform (theContext, myLocation.NormMaxValue, static_cast<Standard_ShortReal> (myNormMaxValue));
myVolumeProgGL->SetUniform (theContext, myLocation.TriCubFilter, static_cast<GLint> (myVolumeSource->TriCubFilter()));
myVolumeProgGL->SetUniform (theContext, myLocation.ApplyShading, static_cast<GLint> (myVolumeSource->ApplyShading()));
myVolumeProgGL->SetUniform (theContext, myLocation.TraceShadows, static_cast<GLint> (myVolumeSource->TraceShadows()));
myVolumeProgGL->SetUniform (theContext, myLocation.RandomShift, static_cast<GLint> (myVolumeSource->RandomShift()));
myVolumeProgGL->SetUniform (theContext, myLocation.IsoSurfaceMode, static_cast<GLint> (myVolumeSource->IsoSurfaceMode()));
//myVolumeProgGL->SetUniform (theContext, myLocation.TraceSliceMode, static_cast<GLint> (myVolumeSource->SliceMode()));
myVolumeProgGL->SetUniform (theContext, myLocation.IsoSurfaceLevel, myVolumeSource->IsoSurfaceLevel());
myVolumeProgGL->SetUniform (theContext, myLocation.TraceSliceLevel, myVolumeSource->SliceLevel());
// Set random seed for to reduce graphic artifacts.
const OpenGl_Vec4 aRandomSeed = OpenGl_Vec4 (static_cast<GLfloat> (rand()),
static_cast<GLfloat> (rand()),
static_cast<GLfloat> (rand()),
static_cast<GLfloat> (rand()));
myVolumeProgGL->SetUniform (theContext, myLocation.RandomSeed, aRandomSeed);
// Set 3D size of single voxel
const BVH_Vec3f aTexelSize = BVH_Vec3f (1.f / aVolumeData->NbVoxelX(),
1.f / aVolumeData->NbVoxelX(),
1.f / aVolumeData->NbVoxelZ());
myVolumeProgGL->SetUniform (theContext, myLocation.VolTexelSize, aTexelSize);
// Set viewing position and orientation
myVolumeProgGL->SetUniform (theContext, myLocation.CameraOriginLB, theOrigins[0]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraOriginRB, theOrigins[1]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraOriginLT, theOrigins[2]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraOriginRT, theOrigins[3]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraDirectLB, theDirects[0]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraDirectRB, theDirects[1]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraDirectLT, theDirects[2]);
myVolumeProgGL->SetUniform (theContext, myLocation.CameraDirectRT, theDirects[3]);
}
namespace
{
struct OpenGl_VolumeDataWrapper
{
//! Returns OpenGL texture format.
virtual OpenGl_TextureFormat Format() const = 0;
//! Returns raw volumetric data.
virtual const GLvoid* Voxels() const = 0;
};
template<class T>
class OpenGl_DenseVolumeDataWrapper : public OpenGl_VolumeDataWrapper
{
private:
const Graphic3d_DenseVolumeData<T>* myData;
public:
//! Creates new wrapper for dense volumetric data.
OpenGl_DenseVolumeDataWrapper (const Graphic3d_VolumeData& theData)
{
myData = static_cast<const Graphic3d_DenseVolumeData<T>* > (&theData);
}
//! Returns OpenGL texture format.
virtual OpenGl_TextureFormat Format() const
{
return OpenGl_TextureFormat::Create<T, 1>();
}
//! Returns raw volumetric data.
virtual const GLvoid* Voxels() const
{
return &myData->Data()->First();
}
};
}
// =======================================================================
// function : UpdateTextures
// purpose :
// =======================================================================
Standard_Boolean OpenGl_Volume::UpdateTextures (const Handle(OpenGl_Context)& theContext) const
{
const Handle(Graphic3d_VolumeData)& aVolumeData = myVolumeSource->VolumeData();
if (aVolumeData.IsNull())
{
return Standard_False;
}
Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams;
// Set linear filtering of TF and volume data
aParams->SetFilter (Graphic3d_TOTF_TRILINEAR);
if (myTransFunctTex.IsNull())
myTransFunctTex = new OpenGl_Texture (aParams);
if (myVolumeDataTex.IsNull())
myVolumeDataTex = new OpenGl_Texture (aParams);
if (myVolumeDataState != aVolumeData->State())
{
#ifdef VOLUME_RENDER_PRINT_INFO
std::cout << "Info: Updating 3D volume texture" << std::endl;
#endif
if (aVolumeData->IsDense())
{
std::auto_ptr<OpenGl_VolumeDataWrapper> aWrapper;
if (typeid (*aVolumeData) == typeid (Graphic3d_DenseVolumeData<GLfloat>))
{
aWrapper.reset (new OpenGl_DenseVolumeDataWrapper<GLfloat> (*aVolumeData));
}
else if (typeid (*aVolumeData) == typeid (Graphic3d_DenseVolumeData<GLubyte>))
{
aWrapper.reset (new OpenGl_DenseVolumeDataWrapper<GLubyte> (*aVolumeData));
}
else if (typeid (*aVolumeData) == typeid (Graphic3d_DenseVolumeData<GLushort>))
{
aWrapper.reset (new OpenGl_DenseVolumeDataWrapper<GLushort> (*aVolumeData));
}
if (aWrapper.get() == NULL)
{
return Standard_False;
}
Standard_Boolean aResult = myVolumeDataTex->Init3D (theContext,
aVolumeData->NbVoxelX(),
aVolumeData->NbVoxelY(),
aVolumeData->NbVoxelZ(),
aWrapper->Format(),
aWrapper->Voxels());
if (!aResult)
{
return Standard_False;
}
}
else
{
// Sparse data are not supported
}
myVolumeDataState = aVolumeData->State();
}
if (myTransFunctState != myVolumeSource->TransferFunction()->State())
{
#ifdef VOLUME_RENDER_PRINT_INFO
std::cout << "Info: Updating transfer function texture" << std::endl;
#endif
Handle(Image_PixMap) anImage = myVolumeSource->TransferFunction()->ImageTable (myNormMinValue,
myNormMaxValue);
if (!myTransFunctTex->Init (theContext, *anImage, Graphic3d_TOT_1D))
{
return Standard_False;
}
myTransFunctState = myVolumeSource->TransferFunction()->State();
}
myVolumeDataTex->Bind (theContext, GL_TEXTURE0);
myTransFunctTex->Bind (theContext, GL_TEXTURE1);
return Standard_True;
}
// =======================================================================
// function : UpdateCamera
// purpose :
// =======================================================================
void OpenGl_Volume::UpdateCamera (const OpenGl_Mat4& theOrientation,
const OpenGl_Mat4& theViewMapping,
OpenGl_Vec3 theOrigins[4],
OpenGl_Vec3 theDirects[4]) const
{
OpenGl_Mat4 theUnviewMat;
// compute inverse model-view-projection matrix
(theViewMapping * theOrientation).Inverted (theUnviewMat);
Standard_Integer aOriginIndex = 0;
Standard_Integer aDirectIndex = 0;
for (Standard_Integer aY = -1; aY <= 1; aY += 2)
{
for (Standard_Integer aX = -1; aX <= 1; aX += 2)
{
OpenGl_Vec4 aOrigin (GLfloat(aX),
GLfloat(aY),
-1.0f,
1.0f);
aOrigin = theUnviewMat * aOrigin;
aOrigin.x() = aOrigin.x() / aOrigin.w();
aOrigin.y() = aOrigin.y() / aOrigin.w();
aOrigin.z() = aOrigin.z() / aOrigin.w();
OpenGl_Vec4 aDirect (GLfloat(aX),
GLfloat(aY),
1.0f,
1.0f);
aDirect = theUnviewMat * aDirect;
aDirect.x() = aDirect.x() / aDirect.w();
aDirect.y() = aDirect.y() / aDirect.w();
aDirect.z() = aDirect.z() / aDirect.w();
aDirect = aDirect - aOrigin;
GLdouble aInvLen = 1.0 / sqrt (aDirect.x() * aDirect.x() +
aDirect.y() * aDirect.y() +
aDirect.z() * aDirect.z());
theOrigins[aOriginIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aOrigin.x()),
static_cast<GLfloat> (aOrigin.y()),
static_cast<GLfloat> (aOrigin.z()));
theDirects[aDirectIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aDirect.x() * aInvLen),
static_cast<GLfloat> (aDirect.y() * aInvLen),
static_cast<GLfloat> (aDirect.z() * aInvLen));
}
}
}
// =======================================================================
// function : Render
// purpose :
// =======================================================================
void OpenGl_Volume::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
Standard_Boolean anIsGL20Supproted =
atof (reinterpret_cast<const char *> (glGetString(GL_VERSION))) >= 2.0;
if (!anIsGL20Supproted)
{
std::cerr << "Error: The current OpenGL version doesn't support Volume Rendering."
<< std::endl << "Info: OpenGL version is must be not lower 2.0." << std::endl;
return ;
}
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
if (!myIsProgramReady)
{
BuildProgram (aContext);
}
const Standard_Integer aSizeX = theWorkspace->Width();
const Standard_Integer aSizeY = theWorkspace->Height();
glDisable (GL_DEPTH_TEST);
myDummyQuad.Bind (aContext);
if (myIsProgramReady)
{
aContext->BindProgram (myVolumeProgGL);
OpenGl_Mat4 aOrientationMatrix = aContext->WorldViewState.Current();
OpenGl_Mat4 aViewMappingMatrix = aContext->ProjectionState.Current();
OpenGl_Vec3 aOrigins[4];
OpenGl_Vec3 aDirects[4];
UpdateCamera (aOrientationMatrix,
aViewMappingMatrix,
aOrigins,
aDirects);
SetUniformValues (aContext,
aOrigins,
aDirects);
myVolumeProgGL->SetUniform (theWorkspace->GetGlContext(), myLocation.TraceSliceMode, myVolumeSource->SliceMode() ? 2 : 0);
aContext->ModelWorldState.Push();
aContext->ProjectionState.Push();
aContext->ModelWorldState.SetIdentity();
aContext->ProjectionState.SetIdentity();
aContext->ApplyModelWorldMatrix();
aContext->ApplyProjectionMatrix();
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
myDummyQuad.BindVertexAttrib (aContext, Graphic3d_TOA_POS);
{
aContext->core20fwd->glVertexAttribPointer (
Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
aContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
}
myDummyQuad.UnbindAttribute (aContext, Graphic3d_TOA_POS);
if (myVolumeSource->SliceMode())
{
glViewport (16,
16,
Min (250, aSizeX - 16),
Min (250, aSizeY - 16));
myVolumeProgGL->SetUniform (theWorkspace->GetGlContext(), myLocation.TraceSliceMode, 1);
myDummyQuad.BindVertexAttrib (aContext, Graphic3d_TOA_POS);
{
aContext->core20fwd->glVertexAttribPointer (
Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
aContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
}
myDummyQuad.UnbindAttribute (aContext, Graphic3d_TOA_POS);
glViewport (0, 0, aSizeX, aSizeY);
}
glDisable (GL_BLEND);
aContext->ModelWorldState.Pop();
aContext->ProjectionState.Pop();
aContext->ApplyModelWorldMatrix();
aContext->ApplyProjectionMatrix();
aContext->BindProgram (NULL);
}
myDummyQuad.Unbind (aContext);
}

View File

@@ -0,0 +1,166 @@
// Created on: 2014-12-10
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef OpenGl_Volume_Header
#define OpenGl_Volume_Header
#include <OpenGl_Texture.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_VertexBuffer.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <Graphic3d_Volume.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
//! Tool object for visualizing volumetric data.
class OpenGl_Volume : public OpenGl_Element
{
public:
//! Creates new 3D volume from the base object.
Standard_EXPORT OpenGl_Volume (const Handle(Graphic3d_Volume)& theVolume);
//! Releases resources of 3D volume.
Standard_EXPORT virtual ~OpenGl_Volume();
public:
//! Releases GPU resources.
Standard_EXPORT virtual void Release (OpenGl_Context* theContext);
//! Performs volumetric rendering with direct ray-casting.
Standard_EXPORT virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
private:
//! Retrieves uniform locations from the shader program.
void GetUniformLocations (const Handle(OpenGl_Context)& theContext) const;
//! Updates volume data and transfer function textures.
Standard_Boolean UpdateTextures (const Handle(OpenGl_Context)& theContext) const;
//! Sets uniform value for active shader program.
void SetUniformValues (const Handle(OpenGl_Context)& theContext,
const OpenGl_Vec3* theOrigins,
const OpenGl_Vec3* theDirects) const;
//! Builds shader program for volume ray-casting.
Standard_Boolean BuildProgram (const Handle(OpenGl_Context)& theContext) const;
//! Updates viewing parameters used in volume ray-casting.
void UpdateCamera (const OpenGl_Mat4& theOrientation,
const OpenGl_Mat4& theViewMapping,
OpenGl_Vec3 theOrigins[4],
OpenGl_Vec3 theDirects[4]) const;
protected:
//! 3D volume source.
Handle(Graphic3d_Volume) myVolumeSource;
//! Ready-to-use state of volumetric data.
mutable Standard_Size myVolumeDataState;
//! Ready-to-use state of transfer function.
mutable Standard_Size myTransFunctState;
//! Is shader program ready?
mutable Standard_Boolean myIsProgramReady;
//! OpenGL 3D volumetric data texture.
mutable Handle(OpenGl_Texture) myVolumeDataTex;
//! OpenGL 1D transfer function texture.
mutable Handle(OpenGl_Texture) myTransFunctTex;
//! Shader program used for volume rendering.
mutable Handle(OpenGl_ShaderProgram) myVolumeProgGL;
//! Stores location of uniform variables.
mutable struct Location
{
GLint BoxCornerMin;
GLint BoxCornerMax;
GLint NumOfSamples;
GLint TriCubFilter;
GLint ApplyShading;
GLint TraceShadows;
GLint RandomShift;
GLint OpacityScale;
GLint VolTexelSize;
GLint NormMinValue;
GLint NormMaxValue;
GLint TransferFunct;
GLint VolumeTexture;
GLint RandomSeed;
GLint CameraOriginLT;
GLint CameraOriginLB;
GLint CameraOriginRT;
GLint CameraOriginRB;
GLint CameraDirectLT;
GLint CameraDirectLB;
GLint CameraDirectRT;
GLint CameraDirectRB;
GLint IsoSurfaceMode;
GLint TraceSliceMode;
GLint IsoSurfaceLevel;
GLint TraceSliceLevel;
Location()
: BoxCornerMin (-1),
BoxCornerMax (-1),
NumOfSamples (-1),
TriCubFilter (-1),
ApplyShading (-1),
TraceShadows (-1),
RandomShift (-1),
OpacityScale (-1),
VolTexelSize (-1),
TransferFunct (-1),
VolumeTexture (-1),
RandomSeed (-1),
CameraOriginLT (-1),
CameraOriginLB (-1),
CameraOriginRT (-1),
CameraOriginRB (-1),
CameraDirectLT (-1),
CameraDirectLB (-1),
CameraDirectRT (-1),
CameraDirectRB (-1),
IsoSurfaceMode (-1),
TraceSliceMode (-1),
IsoSurfaceLevel (-1),
TraceSliceLevel (-1)
{
//
}
} myLocation;
//! Screen-size quad for volume ray-casting.
mutable OpenGl_VertexBuffer myDummyQuad;
//! Normalized min value of the scalar field.
mutable Standard_Real myNormMinValue;
//! Normalized max value of the scalar field.
mutable Standard_Real myNormMaxValue;
public:
DEFINE_STANDARD_ALLOC
};
#endif // OpenGl_Volume_Header

View File

@@ -691,53 +691,6 @@ static Standard_Integer OCC23945 (Draw_Interpretor& /*di*/,Standard_Integer n, c
return 0;
}
#include <Voxel_BoolDS.hxx>
#include <Voxel_FastConverter.hxx>
#include <Voxel_BooleanOperation.hxx>
static Standard_Integer OCC24019 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
if ( argc != 2 ) {
di << "Error: " << argv[0] << " - invalid number of arguments" << "\n";
return 1;
}
TCollection_AsciiString aFileName = argv[1];
TopoDS_Shape aShape;
BRep_Builder aBuilder;
if (!BRepTools::Read(aShape, aFileName.ToCString(), aBuilder)) {
di << "Error: Could not read a shape!" << "\n";
return 1;
}
TopoDS_Solid aShape1 = BRepPrimAPI_MakeSphere(gp_Pnt(20,25,35), 7);
Standard_Real deflection = 0.005;
Standard_Integer nbThreads = 1;
Standard_Integer nbx = 200, nby = 200, nbz = 200;
Voxel_BoolDS theVoxels(0,0,0, 50, 50, 50, nbx, nby, nbz);
Voxel_BoolDS theVoxels1(0,0,0, 50, 50, 50, nbx, nby, nbz);
Standard_Integer progress = 0;
Voxel_FastConverter fcp(aShape, theVoxels, deflection, nbx, nby, nbz, nbThreads);
fcp.ConvertUsingSAT(progress, 1);
fcp.FillInVolume(1);
Voxel_FastConverter fcp1(aShape1, theVoxels1, deflection, nbx, nby, nbz, nbThreads);
fcp1.ConvertUsingSAT(progress, 1);
fcp1.FillInVolume(1);
Voxel_BooleanOperation op;
Standard_Boolean result = op.Cut(theVoxels1, theVoxels);
if ( result != 1 ) {
di << "Error: invalid boolean operation" << "\n";
} else {
di << "OK: boolean operation is ok" << "\n";
}
return 0;
}
//=======================================================================
//function : OCC11758
//purpose :
@@ -1331,34 +1284,6 @@ static Standard_Integer OCC24012 (Draw_Interpretor& di, Standard_Integer argc, c
return 0;
}
#include <Voxel_FastConverter.hxx>
static Standard_Integer OCC24051 (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
{
if (argc != 1) {
di << "Usage : " << argv[0] << " should be one argument (command name only)";
return 1;
}
TopoDS_Shape shape = BRepPrimAPI_MakeBox(gp_Pnt(5, 10, 10), 10, 20, 30).Shape();
Standard_Integer progress = 0;
Standard_Real deflection = 0.005;
Standard_Integer nbx = 200, nby = 200, nbz = 200;
Voxel_BoolDS theVoxels(-50,-50,-30, 100, 100, 100, nbx, nby, nbz);
Voxel_BoolDS theVoxels1(-50,-50,-30, 100, 100, 100, nbx, nby, nbz);
Standard_Integer nbThreads = 5;
Voxel_FastConverter fcp(shape, theVoxels, deflection, nbx, nby, nbz, nbThreads, Standard_True);
#ifdef WNT
#pragma omp parallel for
for(int i = 0; i < nbThreads; i++)
fcp.ConvertUsingSAT(progress, i+1);
#endif
fcp.ConvertUsingSAT(progress);
return 0;
}
#include <BRepFeat_SplitShape.hxx>
#include <ShapeAnalysis_ShapeContents.hxx>
#include <BRepAlgo.hxx>
@@ -3947,7 +3872,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add ("test_offset", "test_offset", __FILE__, test_offset, group);
theCommands.Add ("OCC23945", "OCC23945 surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]", __FILE__, OCC23945,group);
theCommands.Add ("OCC24008", "OCC24008 curve surface", __FILE__, OCC24008, group);
theCommands.Add ("OCC24019", "OCC24019 aShape", __FILE__, OCC24019, group);
theCommands.Add ("OCC11758", "OCC11758", __FILE__, OCC11758, group);
theCommands.Add ("OCC24005", "OCC24005 result", __FILE__, OCC24005, group);
theCommands.Add ("OCC24137", "OCC24137 face vertex U V [N]", __FILE__, OCC24137, group);
@@ -3956,7 +3880,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add ("OCC24370", "OCC24370 edge pcurve surface prec", __FILE__, OCC24370, group);
theCommands.Add ("OCC24533", "OCC24533", __FILE__, OCC24533, group);
theCommands.Add ("OCC24012", "OCC24012 face edge", __FILE__, OCC24012, group);
theCommands.Add ("OCC24051", "OCC24051", __FILE__, OCC24051, group);
theCommands.Add ("OCC24086", "OCC24086 face wire", __FILE__, OCC24086, group);
theCommands.Add ("OCC24622", "OCC24622 texture={1D|2D}\n Tests sourcing of 1D/2D pixmaps for AIS_TexturedShape", __FILE__, OCC24622, group);
theCommands.Add ("OCC24667", "OCC24667 result Wire_spine Profile [Mode [Approx]], no args to get help", __FILE__, OCC24667, group);

49
src/Shaders/TextRender.fs Normal file
View File

@@ -0,0 +1,49 @@
#extension GL_EXT_gpu_shader4 : enable
varying vec2 TexCoord;
uniform sampler2D ColorTexture;
uniform sampler2D DepthTexture;
uniform vec3 Pixel;
#define MAXFLOAT 1.0e15
#define ZERO vec3 (0.0, 0.0, 0.0)
#define ONES vec3 (1.0, 1.0, 1.0)
// =======================================================================
// function : getAlpha
// purpose :
// =======================================================================
float getAlpha()
{
return texture2D (ColorTexture, TexCoord.st).a;
}
#define EPSILON 2.0e-5
// =======================================================================
// function : main
// purpose :
// =======================================================================
void main()
{
vec2 aTexCoord = Pixel.xy / vec2 (textureSize2D (DepthTexture, 0));
vec2 aTexCoord1 = gl_FragCoord.xy / vec2 (textureSize2D (DepthTexture, 0));
vec4 aColor = vec4 (1.0);
aColor.a *= getAlpha();
if (aColor.a <= 0.285)
discard;
if (Pixel.z - EPSILON > texture2D (DepthTexture, aTexCoord).x)
discard;
gl_FragDepth = 0.0;
gl_FragColor = vec4 (aColor.xyz, aColor.a);
}

View File

@@ -0,0 +1,9 @@
varying vec2 TexCoord;
void main (void)
{
TexCoord = occTexCoord.st;
// Do fixed functionality vertex transform
gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
}

402
src/Shaders/VolumeRender.fs Normal file
View File

@@ -0,0 +1,402 @@
// Created on: 2014-12-18
// Created by: Ilya Sevrikov
// Copyright (c) 2013-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//! Pixel coords.
varying vec2 vPixel;
// Viewing position.
uniform vec3 uOriginLT;
uniform vec3 uOriginLB;
uniform vec3 uOriginRT;
uniform vec3 uOriginRB;
// Viewing direction.
uniform vec3 uDirectLT;
uniform vec3 uDirectLB;
uniform vec3 uDirectRT;
uniform vec3 uDirectRB;
// 3D volume bounds.
uniform vec3 uBoxCornerMin;
uniform vec3 uBoxCornerMax;
// 3D volume and TF.
uniform sampler1D uTransferFunct;
uniform sampler3D uVolumeTexture;
// Rendering parameters.
uniform int uNumOfSamples;
uniform int uTriCubFilter;
uniform int uApplyShading;
uniform int uTraceShadows;
uniform int uRandomShift;
uniform vec3 uVolTexelSize;
uniform float uOpacityScale;
uniform float uNormMinValue;
uniform float uNormMaxValue;
uniform vec4 uRandomSeed;
uniform int uIsoSurfaceMode;
uniform int uTraceSliceMode;
uniform float uIsoSurfaceLevel;
uniform float uTraceSliceLevel;
//! Stores ray parameters.
struct SRay
{
vec3 Origin;
vec3 Direct;
};
#define MAXFLOAT 1.0e15
#define ZERO vec3 (0.0, 0.0, 0.0)
#define ONES vec3 (1.0, 1.0, 1.0)
// =======================================================================
// function : GenerateRay
// purpose :
// =======================================================================
SRay GenerateRay (in vec2 thePixel)
{
vec3 aP0 = mix (uOriginLB, uOriginRB, thePixel.x);
vec3 aP1 = mix (uOriginLT, uOriginRT, thePixel.x);
vec3 aD0 = mix (uDirectLB, uDirectRB, thePixel.x);
vec3 aD1 = mix (uDirectLT, uDirectRT, thePixel.x);
vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
return SRay (mix (aP0, aP1, thePixel.y), aDirection);
}
// =======================================================================
// function : IntersectBox
// purpose : Computes ray-box intersection
// =======================================================================
vec2 IntersectBox (in SRay theRay, in vec3 theMinPnt, in vec3 theMaxPnt)
{
vec3 aTimeBoxMin = (theMinPnt - theRay.Origin) * (1.0 / theRay.Direct);
vec3 aTimeBoxMax = (theMaxPnt - theRay.Origin) * (1.0 / theRay.Direct);
vec3 aTimeMax = max (aTimeBoxMin, aTimeBoxMax);
vec3 aTimeMin = min (aTimeBoxMin, aTimeBoxMax);
float aTime1 = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));
float aTime2 = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));
return aTime1 > aTime2 || aTime2 < 0.0 ?
vec2 (MAXFLOAT) : vec2 (max (aTime1, 0.0), aTime2);
}
//=======================================================================
// function : InterpolateCubic
// purpose : Based on 2D cubic interpolation from the paper:
// GPU Gems 2. Fast Third-Order Texture Filtering (Chapter 20)
//=======================================================================
float InterpolateCubic (in vec3 theCoord, in vec3 theCellSize)
{
vec3 aCoordGrid = theCoord / theCellSize - vec3 (0.5);
vec3 aIndex = floor (aCoordGrid);
vec3 aFract = aCoordGrid - aIndex;
vec3 aCompl = vec3 (1.0) - aFract;
vec3 aCompl2 = aCompl * aCompl;
vec3 aFract2 = aFract * aFract;
vec3 aW0 = 1.0 / 6.0 * aCompl2 * aCompl;
vec3 aW1 = vec3 (2.0 / 3.0) - 0.5 * aFract2 * (2.0 - aFract);
vec3 aW2 = vec3 (2.0 / 3.0) - 0.5 * aCompl2 * (2.0 - aCompl);
vec3 aW3 = 1.0 / 6.0 * aFract2 * aFract;
vec3 aG0 = aW0 + aW1;
vec3 aG1 = aW2 + aW3;
vec3 aH0 = (aW1 / aG0) - vec3 (0.5) + aIndex;
vec3 aH1 = (aW3 / aG1) + vec3 (1.5) + aIndex;
aH0 *= theCellSize;
aH1 *= theCellSize;
// fetch the eight linear interpolations
float aTex000 = texture3D (uVolumeTexture, aH0).x;
float aTex100 = texture3D (uVolumeTexture, vec3 (aH1.x, aH0.y, aH0.z)).x;
float aTex010 = texture3D (uVolumeTexture, vec3 (aH0.x, aH1.y, aH0.z)).x;
float aTex110 = texture3D (uVolumeTexture, vec3 (aH1.x, aH1.y, aH0.z)).x;
float aTex001 = texture3D (uVolumeTexture, vec3 (aH0.x, aH0.y, aH1.z)).x;
float aTex101 = texture3D (uVolumeTexture, vec3 (aH1.x, aH0.y, aH1.z)).x;
float aTex011 = texture3D (uVolumeTexture, vec3 (aH0.x, aH1.y, aH1.z)).x;
float aTex111 = texture3D (uVolumeTexture, aH1).x;
// weigh along the z-direction
aTex000 = mix (aTex001, aTex000, aG0.z);
aTex100 = mix (aTex101, aTex100, aG0.z);
aTex010 = mix (aTex011, aTex010, aG0.z);
aTex110 = mix (aTex111, aTex110, aG0.z);
// weigh along the y-direction
aTex000 = mix (aTex010, aTex000, aG0.y);
aTex100 = mix (aTex110, aTex100, aG0.y);
// weigh along the x-direction
return mix (aTex100, aTex000, aG0.x);
}
//=======================================================================
// function : Field
// purpose :
//=======================================================================
float Field (in vec3 thePoint)
{
vec3 aTexCoord = (thePoint - uBoxCornerMin) / (uBoxCornerMax - uBoxCornerMin);
if (uTriCubFilter == 0)
{
return texture3D (uVolumeTexture, aTexCoord).x;
}
return InterpolateCubic (aTexCoord, uVolTexelSize);
}
//=======================================================================
// function : TransferFunction
// purpose :
//=======================================================================
vec4 TransferFunction (in float theValue)
{
return texture1D (uTransferFunct, (theValue - uNormMinValue) / (uNormMaxValue - uNormMinValue));
}
//=======================================================================
// function : FieldNormal
// purpose :
//=======================================================================
vec3 FieldNormal (in vec3 thePoint, in vec3 theView, in float theValue)
{
vec3 aTexCoord = (thePoint - uBoxCornerMin) / (uBoxCornerMax - uBoxCornerMin);
float aPosX = texture3D (uVolumeTexture,
vec3 (aTexCoord.x + uVolTexelSize.x, aTexCoord.y, aTexCoord.z)).x;
float aPosY = texture3D (uVolumeTexture,
vec3 (aTexCoord.x, aTexCoord.y + uVolTexelSize.y, aTexCoord.z)).x;
float aPosZ = texture3D (uVolumeTexture,
vec3 (aTexCoord.x, aTexCoord.y, aTexCoord.z + uVolTexelSize.z)).x;
vec3 aNormal = vec3 (aPosX - theValue,
aPosY - theValue,
aPosZ - theValue) / uVolTexelSize;
float aLength = dot (aNormal, aNormal);
return aLength > 0.0 ? aNormal * inversesqrt (aLength) : theView;
}
//=======================================================================
// function : Rand
// purpose :
//=======================================================================
float Rand (in vec4 theVec)
{
return fract(sin(dot(theVec, uRandomSeed)) * 1000.0);
}
#define MIN_SAMPLES 25
#define MAX_OPACITY 0.99
//=======================================================================
// function : RaytraceVolume
// purpose :
//=======================================================================
vec4 RaytraceVolume (in SRay theRay, in vec2 theRange)
{
float aFraction = theRange.y /
length (uBoxCornerMax - uBoxCornerMin);
int aNbIterations = max (int (uNumOfSamples * aFraction), MIN_SAMPLES);
float aOpacity = uOpacityScale * aFraction / aNbIterations;
vec3 aLight = theRay.Direct;
theRay.Origin += theRange.x * theRay.Direct;
theRay.Direct *= theRange.y / aNbIterations;
vec4 aResult = vec4 (0.0); // result color
if (uRandomShift != 0)
{
theRay.Origin += theRay.Direct * (Rand (vec4 (gl_FragCoord.xy, theRay.Origin.xy)));
}
for (int aStep = 0; aStep < aNbIterations && aResult.w < MAX_OPACITY; ++aStep)
{
float aField = Field (theRay.Origin);
vec4 aColor = TransferFunction (aField);
if (uApplyShading != 0)
{
vec3 aNormal = FieldNormal (theRay.Origin, -theRay.Direct, aField);
aColor.xyz *= max (abs (dot (aNormal, aLight)), 0.2);
}
float anAlpha = (1.0 - aResult.w) * (aColor.w * aOpacity);
aResult = vec4 (aResult.x + anAlpha * aColor.x,
aResult.y + anAlpha * aColor.y,
aResult.z + anAlpha * aColor.z,
aResult.w + anAlpha);
theRay.Origin += theRay.Direct;
}
return aResult;
}
//=======================================================================
// function : illumination
// purpose :
//=======================================================================
vec3 illumination (in vec3 point, in vec3 view, in vec3 normal, in vec3 color)
{
float diffuse = (1.0 + dot (view, normal)) / 2.0;
float specular = pow (max (0.0, dot (view, normal)), 16.0);
return (0.5 * color * (1.0 - diffuse) + color * diffuse) +
0.1 * specular * vec3 (1.0);
}
//=======================================================================
// function : RaytraceIsosurface
// purpose :
//=======================================================================
vec4 RaytraceIsosurface (in SRay theRay, in vec2 theRange)
{
vec4 result = vec4 (0.0);
float fraction = theRange.y /
length (uBoxCornerMax - uBoxCornerMin);
int intervals = max (int (uNumOfSamples * fraction), MIN_SAMPLES);
float step = theRange.y / intervals;
vec3 origin = theRay.Origin + theRange.x * theRay.Direct;
float curr = Field (origin);
float level = uNormMinValue + (uNormMaxValue - uNormMinValue) * uIsoSurfaceLevel;
for (int s = 0; s < intervals; ++s)
{
origin += step * theRay.Direct;
float next = Field (origin);
if ((curr - level) * (next - level) < 0.0)
{
float time = step * (next - level) / (curr - next);
vec3 point = origin + time * theRay.Direct;
float aValue = Field (point);
vec4 color = TransferFunction (aValue);
vec3 normal = FieldNormal (point, -theRay.Direct, aValue);
vec3 shaded = illumination (point, -theRay.Direct, normal, color.xyz);
color = vec4 (shaded.x,
shaded.y,
shaded.z,
1.0);
return color;
}
curr = next;
}
return result;
}
//=======================================================================
// function : RaytraceSlice
// purpose :
//=======================================================================
vec4 RaytraceSlice (in SRay theRay)
{
float aField = Field (theRay.Origin);
vec4 aColor = TransferFunction (aField);
aColor.w *= 2.0;
bool aBorder = vPixel.x < 0.009 || vPixel.y < 0.009 || vPixel.x > 0.99 || vPixel.y > 0.99;
return mix (aColor, vec4 (0.75, 0.75, 0.75, 1.0), float (aBorder));
}
// =======================================================================
// function : main
// purpose :
// =======================================================================
void main()
{
if (uTraceSliceMode == 1)
{
SRay aRay = SRay (uBoxCornerMin +
(uBoxCornerMax - uBoxCornerMin) * vec3 (vPixel.xy, uTraceSliceLevel), vec3 (0.0, 0.0, -1.0));
gl_FragColor = RaytraceSlice (aRay);
return;
}
SRay aRay = GenerateRay (vPixel);
vec3 aBoxMax = uBoxCornerMax;
if (uTraceSliceMode == 2)
{
aBoxMax.z = uBoxCornerMin.z + (uBoxCornerMax.z - uBoxCornerMin.z) * uTraceSliceLevel;
}
vec2 aRange = IntersectBox (aRay, uBoxCornerMin, aBoxMax);
vec4 aColor = vec4 (0.0);
if (aRange.x == MAXFLOAT)
{
discard;
}
aRange.y -= aRange.x;
if (uIsoSurfaceMode == 0)
{
aColor = RaytraceVolume (aRay, aRange);
}
else
{
aColor = RaytraceIsosurface (aRay, aRange);
}
gl_FragColor = aColor;
}

View File

@@ -0,0 +1,12 @@
//! Normalized pixel coordinates.
varying vec2 vPixel;
void main (void)
{
vPixel = vec2 ((occVertex.x + 1.0) * 0.5,
(occVertex.y + 1.0) * 0.5);
vec4 aPosition = occVertex;
gl_Position = occVertex;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,7 @@
Voxel_BoolDS.cxx
Voxel_BoolDS.hxx
Voxel_BooleanOperation.cxx
Voxel_BooleanOperation.hxx
Voxel_CollisionDetection.cxx
Voxel_CollisionDetection.hxx
Voxel_ColorDS.cxx
Voxel_ColorDS.hxx
Voxel_DS.cxx
Voxel_DS.hxx
Voxel_FastConverter.cxx
Voxel_FastConverter.hxx
Voxel_FloatDS.cxx
Voxel_FloatDS.hxx
Voxel_OctBoolDS.cxx
Voxel_OctBoolDS.hxx
Voxel_TypeDef.hxx
Handle_Voxel_Prs.hxx
Voxel_Prs.cxx
Voxel_Prs.hxx
Voxel_Reader.cxx
Voxel_Reader.hxx
Voxel_ROctBoolDS.cxx
Voxel_ROctBoolDS.hxx
Voxel_Selector.cxx
Voxel_Selector.hxx
Voxel_SplitData.cxx
Voxel_SplitData.hxx
Voxel_TypeDef.hxx
Voxel_VisData.h
Voxel_VoxelDisplayMode.hxx
Voxel_VoxelFileFormat.hxx
Voxel_Writer.cxx
Voxel_Writer.hxx
Voxel_BaseReader.hxx
Voxel_DicomReader.hxx
Voxel_DicomReader.cxx

View File

@@ -0,0 +1,30 @@
// Created on: 2014-11-14
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Handle_Voxel_Prs_HeaderFile
#define _Handle_Voxel_Prs_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Handle_AIS_InteractiveObject.hxx>
class Standard_Transient;
class Handle(Standard_Type);
class Handle(AIS_InteractiveObject);
class Voxel_Prs;
DEFINE_STANDARD_HANDLE(Voxel_Prs, AIS_InteractiveObject)
#endif // _Handle_Voxel_Prs_HeaderFile

View File

@@ -0,0 +1,51 @@
// Created on: 2015-01-29
// Created by: Ilya Sevrikov
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Voxel_BaseReader_HeaderFile
#define _Voxel_BaseReader_HeaderFile
#include <Standard.hxx>
#include <TCollection_AsciiString.hxx>
#include <Graphic3d_DenseVolumeData.hxx>
//! Defines abstract reader for read volume data and transfer function
class Voxel_BaseReader
{
public:
//! Creates empty reader.
Voxel_BaseReader()
{
//
}
//! Releases resources.
virtual ~Voxel_BaseReader()
{
//
}
//! Reads volume data from file and returns it.
Standard_EXPORT virtual Standard_Boolean ReadDenseVolumeData (Handle(Graphic3d_VolumeData)& theVolume,
const TCollection_AsciiString& thePath) const = 0;
//! Reads transfer function from file and returns it.
//Standard_EXPORT virtual Handle(Graphic3d_ParentTransferFunction) ReadTransFunc (const TCollection_AsciiString& thePath) const = 0;
};
#endif //_Voxel_BaseReader_HeaderFile

View File

@@ -1,141 +0,0 @@
// Created on: 2008-06-21
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_BoolDS.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};
// 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);
}

View File

@@ -1,230 +0,0 @@
// Created on: 2008-05-21
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Precision.hxx>
#include <Voxel_BoolDS.hxx>
#include <Voxel_BooleanOperation.hxx>
#include <Voxel_ColorDS.hxx>
#include <Voxel_DS.hxx>
#include <Voxel_FloatDS.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, (Standard_Byte)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;
}

View File

@@ -1,295 +0,0 @@
// Created on: 2008-07-16
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <Precision.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <Voxel_BoolDS.hxx>
#include <Voxel_CollisionDetection.hxx>
#include <Voxel_FastConverter.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;
}

View File

@@ -1,173 +0,0 @@
// Created on: 2008-05-08
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_ColorDS.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};
// 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;
}

View File

@@ -1,194 +0,0 @@
// Created on: 2008-05-11
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_DS.hxx>
#include <Voxel_Reader.hxx>
#include <Voxel_Writer.hxx>
// 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
{
GetOrigin(ix, iy, iz, xc, yc, zc);
xc += myHalfDX;
yc += myHalfDY;
zc += myHalfDZ;
}
void Voxel_DS::GetOrigin(const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz,
Standard_Real& x0, Standard_Real& y0, Standard_Real& z0) const
{
x0 = myX + ix * myDX;
y0 = myY + iy * myDY;
z0 = myZ + iz * myDZ;
}
// 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;
}

View File

@@ -0,0 +1,266 @@
#include <Voxel_DicomReader.hxx>
#pragma comment(lib, "gdcmCommon.lib")
#pragma comment(lib, "gdcmDICT.lib")
#pragma comment(lib, "gdcmcharls.lib")
#pragma comment(lib, "gdcmDSED.lib")
#pragma comment(lib, "gdcmexpat.lib")
#pragma comment(lib, "gdcmgetopt.lib")
#pragma comment(lib, "gdcmIOD.lib")
#pragma comment(lib, "gdcmjpeg8.lib")
#pragma comment(lib, "gdcmjpeg12.lib")
#pragma comment(lib, "gdcmjpeg16.lib")
#pragma comment(lib, "gdcmMEXD.lib")
#pragma comment(lib, "gdcmMSFF.lib")
#pragma comment(lib, "gdcmopenjpeg.lib")
#pragma comment(lib, "gdcmzlib.lib")
#pragma comment(lib, "socketxx.lib")
//=========================================
//function : Voxel_DicomReader
//purpose :
//=========================================
Voxel_DicomReader::Voxel_DicomReader()
{
}
#include <NCollection_Array1.hxx>
#include <NCollection_Handle.hxx>
namespace
{
template<class T, bool IsCorrect>
struct DicomTypeCheker
{
/* None */
};
template<class T>
struct DicomTypeCheker<T, true>
{
typedef T Type;
};
template<int Format>
struct DicomTypeSelector
{
/* None */
};
template<>
struct DicomTypeSelector<gdcm::PixelFormat::UINT8>
{
typedef DicomTypeCheker<unsigned char, sizeof (unsigned char) == 1>::Type Type;
};
template<>
struct DicomTypeSelector<gdcm::PixelFormat::UINT16>
{
typedef DicomTypeCheker<unsigned short, sizeof (unsigned short) == 2>::Type Type;
};
template<>
struct DicomTypeSelector<gdcm::PixelFormat::UINT32>
{
typedef DicomTypeCheker<unsigned int, sizeof (unsigned int) == 4>::Type Type;
};
template<>
struct DicomTypeSelector<gdcm::PixelFormat::FLOAT32>
{
typedef DicomTypeCheker<float, sizeof (float) == 4>::Type Type;
};
class DenseVolumeFiller
{
public:
virtual void Push (const Standard_Address theBuffer,
const Standard_Integer theIndexZ) = 0;
virtual Graphic3d_VolumeData* Data() const = 0;
};
template<int Format>
class SpecificDenseVolumeFiller : public DenseVolumeFiller
{
public:
typedef typename DicomTypeSelector<Format>::Type DataType;
public:
SpecificDenseVolumeFiller (const BVH_Box3d& theBounds,
const Standard_Integer theNbVoxX,
const Standard_Integer theNbVoxY,
const Standard_Integer theNbVoxZ)
{
myData = new Graphic3d_DenseVolumeData<DataType> (theBounds,
theNbVoxX,
theNbVoxY,
theNbVoxZ);
}
virtual void Push (const Standard_Address theBuffer,
const Standard_Integer theIndexZ)
{
const Standard_Integer aNbSliceElems = myData->NbVoxelX() *
myData->NbVoxelY();
memcpy (&myData->Data()->ChangeFirst() +
aNbSliceElems * theIndexZ, theBuffer, aNbSliceElems * sizeof (DataType));
}
virtual Graphic3d_VolumeData* Data() const
{
return myData;
}
private:
//! Dense volumetric data of specific type.
Graphic3d_DenseVolumeData<DataType>* myData;
};
}
//========================================================================
//function : ReadDenseVolumeData
//purpose :
//========================================================================
Standard_Boolean Voxel_DicomReader::ReadDenseVolumeData (Handle(Graphic3d_VolumeData)& theVolumeData,
const TCollection_AsciiString& thePath) const
{
gdcm::ImageReader aDicomReader;
gdcm::Directory aFolder;
aFolder.Load (thePath.ToCString());
Standard_ASSERT_RETURN (!aFolder.GetFilenames().empty(),
"Error: There are no any files in the directory", Standard_False);
// read first file to get dataset parameters
aDicomReader.SetFileName (aFolder.GetFilenames().front().c_str());
Standard_ASSERT_RETURN (aDicomReader.Read(),
"Error: Failed to read DICOM image", Standard_False);
gdcm::Image& anImage = aDicomReader.GetImage();
Standard_ASSERT_RETURN (!anImage.IsEmpty(),
"Error: DICOM image is empty", Standard_False);
const Standard_Integer aDimX = anImage.GetDimension (0);
const Standard_Integer aDimY = anImage.GetDimension (1);
const gdcm::PixelFormat aType = anImage.GetPixelFormat();
BVH_Box3d aBounds (BVH_Vec3d (anImage.GetOrigin (0), anImage.GetOrigin (1), anImage.GetOrigin (2)),
BVH_Vec3d (anImage.GetOrigin (0), anImage.GetOrigin (1), anImage.GetOrigin (2)));
aBounds.CornerMax().x() += aDimX * anImage.GetSpacing (0);
aBounds.CornerMax().y() += aDimY * anImage.GetSpacing (1);
NCollection_Handle<DenseVolumeFiller> aVolumeFiller = NULL;
switch (aType)
{
case gdcm::PixelFormat::UINT8:
{
aVolumeFiller = new SpecificDenseVolumeFiller<gdcm::PixelFormat::UINT8> (
aBounds, aDimX, aDimY, static_cast<Standard_Integer> (aFolder.GetFilenames().size()));
} break;
case gdcm::PixelFormat::UINT16:
{
aVolumeFiller = new SpecificDenseVolumeFiller<gdcm::PixelFormat::UINT16> (
aBounds, aDimX, aDimY, static_cast<Standard_Integer> (aFolder.GetFilenames().size()));
} break;
case gdcm::PixelFormat::UINT32:
{
aVolumeFiller = new SpecificDenseVolumeFiller<gdcm::PixelFormat::UINT32> (
aBounds, aDimX, aDimY, static_cast<Standard_Integer> (aFolder.GetFilenames().size()));
} break;
case gdcm::PixelFormat::FLOAT32:
{
aVolumeFiller = new SpecificDenseVolumeFiller<gdcm::PixelFormat::FLOAT32> (
aBounds, aDimX, aDimY, static_cast<Standard_Integer> (aFolder.GetFilenames().size()));
} break;
}
if (aVolumeFiller.IsNull())
{
return Standard_False; // unsupported pixel format
}
double aSizeZ = 0.0;
for (std::vector<std::string>::const_iterator anIt = aFolder.GetFilenames().begin(); anIt != aFolder.GetFilenames().end(); ++anIt)
{
if (anIt != aFolder.GetFilenames().begin())
{
// Sometimes gdcm::ImageReader::GetImage() throw exception.
// This magic solves this trouble
gdcm::File* aFile = new gdcm::File;
aDicomReader.SetFile (*aFile);
aDicomReader.SetFileName (anIt->c_str());
if (!aDicomReader.CanRead())
{
continue;
}
std::cout << anIt->c_str() << std::endl;
Standard_ASSERT_RETURN (aDicomReader.Read(),
"Error: Failed to read DICOM image", Standard_False);
anImage = aDicomReader.GetImage();
Standard_ASSERT_RETURN (!anImage.IsEmpty(),
"Error: DICOM image is empty", Standard_False);
if (aDimX != static_cast<Standard_Integer>(anImage.GetDimension (0))
|| aDimY != static_cast<Standard_Integer>(anImage.GetDimension (1))
|| aType != anImage.GetPixelFormat())
{
return Standard_False;
}
}
aSizeZ += anImage.GetSpacing (2);
if (anIt == aFolder.GetFilenames().end() - 1)
{
//aBounds.CornerMax().z() = anImage.GetOrigin (2); // TODO: ?
aBounds.CornerMax().z() = Max (anImage.GetOrigin (2), aBounds.CornerMax().z() + aSizeZ);
}
const gdcm::PhotometricInterpretation& aPI = anImage.GetPhotometricInterpretation();
if (aPI.GetType() == gdcm::PhotometricInterpretation::MONOCHROME1
|| aPI.GetType() == gdcm::PhotometricInterpretation::MONOCHROME2)
{
Standard_Character* aBuffer = new Standard_Character[anImage.GetBufferLength()];
if (!anImage.GetBuffer (aBuffer))
{
return Standard_False;
}
aVolumeFiller->Push (aBuffer, anIt - aFolder.GetFilenames().begin());
delete [] aBuffer;
}
else
{
return Standard_False;
}
}
theVolumeData = aVolumeFiller->Data();
theVolumeData->SetBounds (aBounds);
return Standard_True;
}

View File

@@ -0,0 +1,42 @@
// Created on: 2015-01-29
// Created by: Ilya Sevrikov
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Voxel_DicomReader_HeaderFile
#define _Voxel_DicomReader_HeaderFile
#include <Voxel_BaseReader.hxx>
#include <OSD_OpenFile.hxx>
#include <Standard.hxx>
#include <TCollection_AsciiString.hxx>
#include <gdcmImageReader.h>
#include <gdcmImage.h>
#include <gdcmPhotometricInterpretation.h>
#include <gdcmDirectory.h>
//! Defines reader class for reading dicom files.
class Voxel_DicomReader : public Voxel_BaseReader
{
public:
//! Creates dicom reader and fills dictionaries.
Standard_EXPORT Voxel_DicomReader();
//! Reads volume data from directory and returns it.
Standard_EXPORT Standard_Boolean ReadDenseVolumeData (Handle(Graphic3d_VolumeData)& theVolume,
const TCollection_AsciiString& thePath) const;
};
#endif //_Voxel_DicomReader_HeaderFile

File diff suppressed because it is too large Load Diff

View File

@@ -1,116 +0,0 @@
// Created on: 2008-05-15
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_FloatDS.hxx>
#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];
}

View File

@@ -274,6 +274,8 @@ void Voxel_OctBoolDS::OptimizeMemory()
value = itr.Value();
if (value == 0 || value == 255)
{
xyz = itr.Key();
ixs.Append(xyz.ix);
iys.Append(xyz.iy);

View File

@@ -1,4 +1,4 @@
// Created on: 2008-05-13
// Created on: 2014-12-17
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
@@ -13,294 +13,55 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_Prs.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_MaterialAspect.hxx>
#include <Poly_Triangulation.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_Root.hxx>
#include <Quantity_Color.hxx>
#include <Standard_Type.hxx>
#include <Voxel_Prs.hxx>
#include "Voxel_VisData.h"
Voxel_Prs::Voxel_Prs():AIS_InteractiveObject(PrsMgr_TOP_AllView),myVisData(0)
IMPLEMENT_STANDARD_HANDLE (Voxel_Prs, AIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT(Voxel_Prs, AIS_InteractiveObject)
//========================================================================
//function : Voxel_Prs
//purpose :
//========================================================================
Voxel_Prs::Voxel_Prs() : AIS_InteractiveObject (PrsMgr_TOP_AllView)
{
//
}
void Voxel_Prs::SetBoolVoxels(const Standard_Address theVoxels)
//========================================================================
//function : ~Voxel_Prs
//purpose :
//========================================================================
Voxel_Prs::~Voxel_Prs()
{
Allocate();
((Voxel_VisData*)myVisData)->myBoolVoxels = (Voxel_BoolDS*) theVoxels;
//
}
void Voxel_Prs::SetColorVoxels(const Standard_Address theVoxels)
//========================================================================
//function : Compute
//purpose :
//========================================================================
void Voxel_Prs::Compute (const Handle(PrsMgr_PresentationManager3d)& /*theMgr*/,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer /*theMode*/)
{
Allocate();
((Voxel_VisData*)myVisData)->myColorVoxels = (Voxel_ColorDS*) theVoxels;
}
thePrs->Clear();
void Voxel_Prs::SetROctBoolVoxels(const Standard_Address theVoxels)
{
Allocate();
((Voxel_VisData*)myVisData)->myROctBoolVoxels = (Voxel_ROctBoolDS*) theVoxels;
}
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
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)
if (!aGroup.IsNull())
{
// 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;
aGroup->AddVolume (myVolume);
}
}
void Voxel_Prs::Allocate()
//========================================================================
//function : ComputeSelection
//purpose :
//========================================================================
void Voxel_Prs::ComputeSelection (const Handle(SelectMgr_Selection)& /*theSelection*/,
const Standard_Integer /*theMode*/)
{
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;
// TODO
}

View File

@@ -1,4 +1,4 @@
// Created on: 2008-05-06
// Created on: 2008-05-13
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
@@ -16,134 +16,60 @@
#ifndef _Voxel_Prs_HeaderFile
#define _Voxel_Prs_HeaderFile
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <Standard_Address.hxx>
#include <Handle_Voxel_Prs.hxx>
#include <AIS_InteractiveObject.hxx>
#include <Voxel_VoxelDisplayMode.hxx>
#include <Quantity_HArray1OfColor.hxx>
#include <Standard_Real.hxx>
#include <Standard_Integer.hxx>
#include <PrsMgr_PresentationManager3d.hxx>
#include <Handle_Prs3d_Presentation.hxx>
#include <Handle_SelectMgr_Selection.hxx>
#include <Prs3d_Presentation.hxx>
#include <SelectMgr_Selection.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Byte.hxx>
class Poly_Triangulation;
class Quantity_Color;
class Prs3d_Presentation;
#include <Graphic3d_VolumeData.hxx>
#include <Graphic3d_TransferFunction.hxx>
class Voxel_Prs;
DEFINE_STANDARD_HANDLE(Voxel_Prs, AIS_InteractiveObject)
//! Interactive object for voxels.
//! Interactive object for volumetric data.
class Voxel_Prs : public AIS_InteractiveObject
{
public:
//! Creates empty voxel presentation.
Standard_EXPORT Voxel_Prs();
//! Releases resources of voxel presentation.
Standard_EXPORT ~Voxel_Prs();
public:
//! An empty constructor.
Standard_EXPORT Voxel_Prs();
//! <theVoxels> is a Voxel_BoolDS* object.
Standard_EXPORT void SetBoolVoxels (const Standard_Address theVoxels);
//! <theVoxels> is a Voxel_ColorDS* object.
Standard_EXPORT void SetColorVoxels (const Standard_Address theVoxels);
//! <theVoxels> is a Voxel_ROctBoolDS* object.
Standard_EXPORT void SetROctBoolVoxels (const Standard_Address theVoxels);
//! Sets a triangulation for visualization.
Standard_EXPORT void SetTriangulation (const Handle(Poly_Triangulation)& theTriangulation);
//! Sets a display mode for voxels.
Standard_EXPORT void SetDisplayMode (const Voxel_VoxelDisplayMode theMode);
//! Defines the color of points, quadrangles ... for BoolDS.
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
//! 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.
Standard_EXPORT void SetColors (const Handle(Quantity_HArray1OfColor)& theColors);
//! Defines the size of points for all types of voxels.
Standard_EXPORT void SetPointSize (const Standard_Real theSize);
//! Defines the size of quadrangles in per cents (0 .. 100).
Standard_EXPORT void SetQuadrangleSize (const Standard_Integer theSize);
//! Defines the transparency value [0 .. 1] for quadrangular visualization.
Standard_EXPORT virtual void SetTransparency (const Standard_Real theTransparency) Standard_OVERRIDE;
//! 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.
Standard_EXPORT void Highlight (const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz);
//! A destructor of presentation data.
Standard_EXPORT void Destroy();
~Voxel_Prs()
{
Destroy();
}
//! Simplifies visualization of voxels in case of view rotation, panning and zooming.
Standard_EXPORT void SetDegenerateMode (const Standard_Boolean theDegenerate);
//! 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.
Standard_EXPORT void SetUsageOfGLlists (const Standard_Boolean theUsage);
//! Switches visualization of points from smooth to rough.
Standard_EXPORT void SetSmoothPoints (const Standard_Boolean theSmooth);
//! Defines min-max values for visualization of voxels of ColorDS structure.
//! By default, min value = 1, max value = 15 (all non-zero values).
Standard_EXPORT void SetColorRange (const Standard_Byte theMinValue, const Standard_Byte theMaxValue);
//! Defines the displayed area of voxels.
//! By default, the range is equal to the box of voxels (all voxels are displayed).
Standard_EXPORT void 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);
//! Returns 3D volume object.
Handle(Graphic3d_Volume) Volume() const
{
return myVolume;
}
DEFINE_STANDARD_RTTI(Voxel_Prs,AIS_InteractiveObject)
//! Sets 3D volume object.
void SetVolume (const Handle(Graphic3d_Volume)& theVolume)
{
myVolume = theVolume;
}
protected:
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode = 0) Standard_OVERRIDE;
//! Computes 3D volume presentation.
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& theManager,
const Handle(Prs3d_Presentation)& thePresentation,
const Standard_Integer theMode = 0);
//! Computes 3D volume selection.
Standard_EXPORT void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode);
protected:
private:
Standard_EXPORT void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, const Standard_Integer theMode);
//! Allocates the data structure of visualization.
Standard_EXPORT void Allocate();
Standard_Address myVisData;
//! 3D volume object.
Handle(Graphic3d_Volume) myVolume;
public:
DEFINE_STANDARD_RTTI (Voxel_Prs)
};
#endif // _Voxel_Prs_HeaderFile
#endif // _Voxel_Prs_HeaderFile

View File

@@ -1,727 +0,0 @@
// Created on: 2008-09-01
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Voxel_ROctBoolDS.hxx>
#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;
}
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]);
((Voxel_SplitData**)myData)[ix] = 0;
}
}
}
}
// 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;
}
}
}

View File

@@ -1,539 +0,0 @@
// Created on: 2008-08-28
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OSD_OpenFile.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Voxel_BoolDS.hxx>
#include <Voxel_ColorDS.hxx>
#include <Voxel_FloatDS.hxx>
#include <Voxel_Reader.hxx>
#include <Voxel_TypeDef.hxx>
#include <Voxel_VoxelFileFormat.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 = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
// Read the header
Standard_Byte type; // 0 - bool, 1 - color, 2 - float
Voxel_VoxelFileFormat format;
Standard_Character svoxels[9], sformat[9], stype[9];
fscanf(f, "%8s %8s %8s\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 = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
Standard_Character line[65], sx[33], sy[33], sz[33];
// 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, "%32s %32s %32s\n", sx, sy, sz) != 3)
{
fclose(f);
return Standard_False;
}
x = Atof(sx); y = Atof(sy); z = Atof(sz);
if (fscanf(f, "%32s %32s %32s\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] = (Standard_Byte)value;
}
}
fclose(f);
return Standard_True;
}
Standard_Boolean Voxel_Reader::ReadColorAsciiVoxels(const TCollection_ExtendedString& file)
{
// Open file for reading
FILE* f = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
Standard_Character line[65], sx[33], sy[33], sz[33];
// 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, "%32s %32s %32s\n", sx, sy, sz) != 3)
{
fclose(f);
return Standard_False;
}
x = Atof(sx); y = Atof(sy); z = Atof(sz);
if (fscanf(f, "%32s %32s %32s\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] = (Standard_Byte)value;
}
}
fclose(f);
return Standard_True;
}
Standard_Boolean Voxel_Reader::ReadFloatAsciiVoxels(const TCollection_ExtendedString& file)
{
// Open file for reading
FILE* f = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
Standard_Character line[65], sx[33], sy[33], sz[33];
// 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, "%32s %32s %32s\n", sx, sy, sz) != 3)
{
fclose(f);
return Standard_False;
}
x = Atof(sx); y = Atof(sy); z = Atof(sz);
if (fscanf(f, "%32s %32s %32s\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 %64s\n", &i1, &i2, line) != 3)
{
fclose(f);
return Standard_False;
}
}
else
{
if (sscanf(line, "%d %64s\n", &i2, line) != 2)
{
fclose(f);
return Standard_False;
}
}
value = (Standard_ShortReal)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 = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
// Header: skip it
Standard_Character line[65];
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] = (Standard_Byte)value;
}
}
fclose(f);
return Standard_True;
}
Standard_Boolean Voxel_Reader::ReadColorBinaryVoxels(const TCollection_ExtendedString& file)
{
// Open file for reading
FILE* f = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
// Header: skip it
Standard_Character line[65];
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] = (Standard_Byte)value;
}
}
fclose(f);
return Standard_True;
}
Standard_Boolean Voxel_Reader::ReadFloatBinaryVoxels(const TCollection_ExtendedString& file)
{
// Open file for reading
FILE* f = OSD_OpenFile(file, "r");
if (!f)
return Standard_False;
// Header: skip it
Standard_Character line[65];
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;
}

View File

@@ -1,581 +0,0 @@
// Created on: 2008-07-30
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <IntAna_IntConicQuad.hxx>
#include <IntAna_Quadric.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <V3d_View.hxx>
#include <Voxel_BoolDS.hxx>
#include <Voxel_ColorDS.hxx>
#include <Voxel_ROctBoolDS.hxx>
#include <Voxel_Selector.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;
}

View File

@@ -38,16 +38,20 @@ inline Standard_Boolean IsEqual(const iXYZ& one, const iXYZ& two)
#include <NCollection_DataMap.hxx>
typedef NCollection_DataMap<iXYZ, Standard_Integer> iXYZIndex;
typedef NCollection_DataMap<iXYZ, Standard_Byte> iXYZBool;
template<typename T>
struct iXYZMap
{
typedef NCollection_DataMap<iXYZ, T> Type;
};
// Defines
#define VOXELS "Voxels"
#define ASCII "Ascii"
#define BINARY "Binary"
#define BOOL "Bool"
#define COLOR "Color"
#define FLOAT "Float"
#define VOXELS "Voxels"
#define ASCII "Ascii"
#define BINARY "Binary"
#define BOOL "Bool"
#define COLOR "Color"
#define FLOAT "Float"
#define VOXELTEMPLATE "VoxelTemplate"
#endif // _VOXEL_TYPEDEF_HXX_

View File

@@ -1,129 +0,0 @@
/*
Copyright (c) 1999-2014 OPEN CASCADE SAS
This file is part of Open CASCADE Technology software library.
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License version 2.1 as published
by the Free Software Foundation, with special exception defined in the file
OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
distribution for complete text of the license and disclaimer of any warranty.
Alternatively, this file may be used under the terms of Open CASCADE
commercial license or contractual agreement.
*/
#ifndef _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_

View File

@@ -1,442 +0,0 @@
// Created on: 2008-08-28
// Created by: Vladislav ROMASHKO
// Copyright (c) 2008-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OSD_OpenFile.hxx>
#include <Precision.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Voxel_BoolDS.hxx>
#include <Voxel_ColorDS.hxx>
#include <Voxel_FloatDS.hxx>
#include <Voxel_TypeDef.hxx>
#include <Voxel_Writer.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 = OSD_OpenFile(file, "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 = OSD_OpenFile(file, "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 = OSD_OpenFile(file, "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 = OSD_OpenFile(file, "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 = OSD_OpenFile(file, "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 = OSD_OpenFile(file, "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::SquareConfusion();
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;
}