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:
@@ -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.
|
||||
|
@@ -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
|
582
src/Graphic3d/Graphic3d-936bf93.cdl
Normal file
582
src/Graphic3d/Graphic3d-936bf93.cdl
Normal 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;
|
131
src/Graphic3d/Graphic3d_DenseVolumeData.hxx
Normal file
131
src/Graphic3d/Graphic3d_DenseVolumeData.hxx
Normal 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
|
127
src/Graphic3d/Graphic3d_DenseVolumeData.lxx
Normal file
127
src/Graphic3d/Graphic3d_DenseVolumeData.lxx
Normal 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;
|
||||
}
|
@@ -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 :
|
||||
|
296
src/Graphic3d/Graphic3d_RgbaTransferFunction.hxx
Normal file
296
src/Graphic3d/Graphic3d_RgbaTransferFunction.hxx
Normal 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
|
178
src/Graphic3d/Graphic3d_RgbaTransferFunction.lxx
Normal file
178
src/Graphic3d/Graphic3d_RgbaTransferFunction.lxx
Normal 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;
|
||||
}
|
@@ -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)
|
74
src/Graphic3d/Graphic3d_TransferFunction.hxx
Normal file
74
src/Graphic3d/Graphic3d_TransferFunction.hxx
Normal 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
|
52
src/Graphic3d/Graphic3d_TransferFunctionFilter.hxx
Normal file
52
src/Graphic3d/Graphic3d_TransferFunctionFilter.hxx
Normal 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
|
33
src/Graphic3d/Graphic3d_TransferFunctionLinearFilter.hxx
Normal file
33
src/Graphic3d/Graphic3d_TransferFunctionLinearFilter.hxx
Normal 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
|
70
src/Graphic3d/Graphic3d_TransferFunctionLinearFilter.lxx
Normal file
70
src/Graphic3d/Graphic3d_TransferFunctionLinearFilter.lxx
Normal 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;
|
||||
}
|
33
src/Graphic3d/Graphic3d_TransferFunctionNearestFilter.hxx
Normal file
33
src/Graphic3d/Graphic3d_TransferFunctionNearestFilter.hxx
Normal 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
|
70
src/Graphic3d/Graphic3d_TransferFunctionNearestFilter.lxx
Normal file
70
src/Graphic3d/Graphic3d_TransferFunctionNearestFilter.lxx
Normal 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;
|
||||
}
|
||||
}
|
47
src/Graphic3d/Graphic3d_TransferFunctionNode.hxx
Normal file
47
src/Graphic3d/Graphic3d_TransferFunctionNode.hxx
Normal 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
|
73
src/Graphic3d/Graphic3d_Volume.cxx
Normal file
73
src/Graphic3d/Graphic3d_Volume.cxx
Normal 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;
|
||||
}
|
||||
|
239
src/Graphic3d/Graphic3d_Volume.hxx
Normal file
239
src/Graphic3d/Graphic3d_Volume.hxx
Normal 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
|
78
src/Graphic3d/Graphic3d_VolumeData.cxx
Normal file
78
src/Graphic3d/Graphic3d_VolumeData.cxx
Normal 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));
|
||||
}
|
147
src/Graphic3d/Graphic3d_VolumeData.hxx
Normal file
147
src/Graphic3d/Graphic3d_VolumeData.hxx
Normal 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
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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 :
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
520
src/OpenGl/OpenGl_Volume.cxx
Normal file
520
src/OpenGl/OpenGl_Volume.cxx
Normal 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);
|
||||
}
|
166
src/OpenGl/OpenGl_Volume.hxx
Normal file
166
src/OpenGl/OpenGl_Volume.hxx
Normal 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
|
@@ -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
49
src/Shaders/TextRender.fs
Normal 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);
|
||||
}
|
9
src/Shaders/TextRender.vs
Normal file
9
src/Shaders/TextRender.vs
Normal 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
402
src/Shaders/VolumeRender.fs
Normal 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;
|
||||
}
|
12
src/Shaders/VolumeRender.vs
Normal file
12
src/Shaders/VolumeRender.vs
Normal 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
@@ -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
|
30
src/Voxel/Handle_Voxel_Prs.hxx
Normal file
30
src/Voxel/Handle_Voxel_Prs.hxx
Normal 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
|
51
src/Voxel/Voxel_BaseReader.hxx
Normal file
51
src/Voxel/Voxel_BaseReader.hxx
Normal 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
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
266
src/Voxel/Voxel_DicomReader.cxx
Normal file
266
src/Voxel/Voxel_DicomReader.cxx
Normal 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;
|
||||
}
|
42
src/Voxel/Voxel_DicomReader.hxx
Normal file
42
src/Voxel/Voxel_DicomReader.hxx
Normal 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
@@ -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];
|
||||
}
|
@@ -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);
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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_
|
||||
|
@@ -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_
|
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user