1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-24 13:50:49 +03:00

Compare commits

...

10 Commits

Author SHA1 Message Date
isk
03681e2592 Add VUpdateVertices draw command. 2016-03-23 07:51:55 +03:00
isk
64fd2e605c Fix pathtrace. 2016-03-18 12:46:20 +03:00
isk
c893090668 update script 2016-03-18 12:46:19 +03:00
isk
3f8261e1ca Update video script 2016-03-18 12:46:17 +03:00
isk
9ce7a1be6e Update path tracing. 2016-03-18 12:46:15 +03:00
unknown
ee72373b8d Increase number of texture.
Fix topdown record video.
Upgrade sample.
2016-03-18 12:45:07 +03:00
isk
5c52d14a08 Add loader *.obj files. 2016-03-18 12:45:05 +03:00
isk
54573faf41 0025382: Visualization, TKOpenGl - improved video recording capability
OSD_Timer::ElapsedTime() - fix accumulation of the error.
Provide new command vanimation for animation playline definition.

Extend vanimation command with video recorder

* * *
pload MODELING VISUALIZATION
box b1 1 2 3
vinit View1
vclear
vaxo
vsetdispmode 1
vdisplay b1
vfit
vsetlocation b1 0 1 0

proc anim1 {thePts thePtsLoc theName} { vsetlocation b1 [expr sin($thePtsLoc)] cos($thePtsLoc)] 0 }
vanim anim1 -reset -onRedraw anim1
vanim anim  -reset -addSlice 0.0 30.0 anim1
vanim -play anim -playFps 30 -record test.mkv -recWidth 1920 -recHeight 1080

Added command vlogo

Ported on current master.

Removed vlogo command and logo layer item as unused.
2016-03-18 12:45:03 +03:00
isk
a9cc8b1a3b 0026434: Visualization - Textured objects should have priority over the environment mapping.
Add handle on environment texture in OpenGl_Workspace.
Add a new parameter UseEnvironmentTexture to the Graphic3d_ZLayerSettings.
OSD layers don't use environment texture by default.
zbuffertrihedron doesn't use environment texture.
vzlayer can enable/disable environment texture mappping.
Delete unnecessary files Graphic3d_TypeOfSurfaceDetail.hxx and V3d_TypeOfSurface.hxx.
Delete functions SurfaceDetailType and SetSurfaceDetailType functions from Graphic3d_CView.
Delete functions SurfaceDetailState and UpdateSurfaceDetailStateTo from OpenGl_ShaderManager.
Delete class OpenGl_SurfaceDetailState.
Delete functions SurfaceDetailType and SetSurfaceDetailType from OpenGl_View.
Delete functions SetSurfaceDetail and SurfaceDetail() from V3d_View.
Delete functions SetDefaultSurfaceDetail and DefaultSurfaceDetail from V3d_Viewer.
Delete draw command VSetTextureMode.
Add description in dox.
2016-03-18 12:45:01 +03:00
Denis BOGOLEPOV
2b5550fae8 0027223: Visualization, Ray Tracing - add support of clipping planes 2016-03-18 12:44:33 +03:00
61 changed files with 5812 additions and 504 deletions

View File

@@ -971,3 +971,11 @@ Zoom persistent selection introduces a new structure *Graphic3d_TransformPers* f
* Transformation matrix utilities from *OpenGl_Utils* namespace have been moved to *Graphic3d_TransformUtils* and *Graphic3d_TransformUtils.hxx* header respectively.
* Matrix stack utilities from *OpenGl_Utils* namespace have been moved to *OpenGl_MatrixStack* class and *OpenGl_MatrixStack.hxx* header respectively.
* *OpenGl_View* methods *Begin/EndTransformPersistence* have been removed. Please, use *Graphic3d_TransformPers::Apply()* instead to apply persistence to perspective and world-view projection matrices.
Applications that use gp_Quaternion to convert Yaw-Pitch-Roll angles (or other intrinsic Tait-Bryan sequences) may need to be updated to take this change into account.
@subsection Correction of texture mapping of objects
Interaction of texture and environment texture is fixed. Textured objects have priority over the environment mapping.
Redundant enumerations V3d_TypeOfSurface and Graphic3d_TypeOfSurface, class OpenGl_SurfaceDetailState, corresponding methods from Graphic3d_CView, OpenGl_ShaderManager, OpenGl_View, V3d_View, V3d_Viewer are deleted.
Draw command VSetTextureMode is deleted.

View File

@@ -75,4 +75,8 @@ vbsdf r -kd 0.5 0.9 0.3 -ks 0.0 -kr 0.3 -n
vbsdf r -fresnel Constant 1.0
vsetlocation r 0.5 0.65 0.1
vclipplane create pln
vclipplane change pln equation 0 0 -1 0.1
vclipplane set pln object s
vrenderparams -ray -gi -rayDepth 8

485
samples/tcl/video.tcl Normal file
View File

@@ -0,0 +1,485 @@
pload ALL
vclear
vclose all
# Declaration global variables
global startTimeTyre
global currentTimeTyre
global endTimeTyre
global stepTimeTyre
global index
global paveStartKd
global paveStartKt
global paveCurrentKd
global paveCurrentKt
global paveDeltaKd
global paveDeltaKt
global tyrePlaneStartDistance
global tyrePlaneCurrentDistance
global tyrePlaneDeltaDistance
global tyrePlaneEndDistance
global folderTyre
global folderTyre
global folderVideo
global width
global height
set index 0
set startTimeTyre 4805
set currentTimeTyre 4805
set endTimeTyre 5690
set stepTimeTyre 15
set SamplesPerPixel 256
set folderTyre "D:/TmpFiles/for_video/Tyre"
set folderEnv "D:/TmpFiles/for_video/Environment"
set folderVideo "D:/TmpFiles/for_video/HighQuality"
set width 1280
set height 720
#set width 640
#set height 360
# Settings
set isEditLight 1
set isGI 1
set isAnim 1
set paveStartKd 0.243137
set paveStartKt 0.0
set paveCurrentKd ${paveStartKd}
set paveCurrentKt ${paveStartKt}
#set paveDeltaKd 0.0020448142
set paveDeltaKd 0.0030392125
#set paveDeltaKt 0.0114285714
set paveDeltaKt 0.0125
set tyrePlaneStartDistance 310
set tyrePlaneCurrentDistance ${tyrePlaneStartDistance}
set tyrePlaneDeltaDistance 1.5
set tyrePlaneEndDistance 190
vinit name=View1 w=${width} h=${height} t=0 l=0
vsetdispmode 1
vcamera -persp -fovy 60
#vzbufftrihedron
#building0
puts "Loading the first building..."
vdisplayobj building0 "${folderEnv}/Scene Building0.obj"
vbsdf building0 -kd 0.6
#grass0
puts "Loading the first grass..."
vdisplayobj grass0 "${folderEnv}/Scene Grass0.obj"
vsetmaterial grass0 plastic
vbsdf grass0 -kd 0.113 0.306 0.008
#bench0
puts "Loading the first bench..."
vdisplayobj bench0 "${folderEnv}/Scene Bench0.obj"
#bench1
puts "Loading the second bench..."
vdisplayobj bench1 "${folderEnv}/Scene Bench1.obj"
#urn
puts "Loading the urn..."
vdisplayobj urn "${folderEnv}/Scene Urn.obj"
vsetmaterial urn aluminium
vbsdf urn -ks 0.6
vbsdf urn -roughness 8
#pave00
puts "Loading the first pave..."
vdisplayobj pave00 "${folderEnv}/Scene Pave00.obj"
vsetmaterial pave00 stone
#pavement0
puts "Loading the first pavement..."
vdisplayobj pavement0 "${folderEnv}/Scene Pavement0.obj"
#pave01
puts "Loading the second pave..."
vdisplayobj pave01 "${folderEnv}/Scene Pave01.obj"
vsetmaterial pave01 stone
#Tree00
vdisplayobj tree00 "${folderEnv}/Scene Tree00.obj"
vbsdf tree00 -ks 0 -kd 1
#Tree01
vdisplayobj tree01 "${folderEnv}/Scene Tree01.obj"
vbsdf tree01 -ks 0 -kd 1
#building1
puts "Loading the second building..."
vdisplayobj building1 "${folderEnv}/Scene Building1.obj"
vbsdf building1 -kd 0.6
#grass1
puts "Loading the second grass..."
vdisplayobj grass1 "${folderEnv}/Scene Grass1.obj"
vsetmaterial grass1 plastic
vbsdf grass1 -kd 0.113 0.306 0.008
#pave10
puts "Loading the second pave..."
vdisplayobj pave10 "${folderEnv}/Scene Pave10.obj"
vsetmaterial pave10 stone
#pavement
vdisplayobj pavement1 "${folderEnv}/Scene Pavement1.obj"
#pave11
vdisplayobj pave11 "${folderEnv}/Scene Pave11.obj"
vsetmaterial pave11 stone
#Tree10
vdisplayobj tree1 "${folderEnv}/Scene Tree10.obj"
vbsdf tree1 -ks 0 -kd 1
#building2
puts "Loading the third building..."
vdisplayobj building2 "${folderEnv}/Scene Building2.obj"
vbsdf building2 -kd 0.4
#grass2
puts "Loading the third grass..."
vdisplayobj grass2 "${folderEnv}/Scene Grass2.obj"
vsetmaterial grass2 plastic
vbsdf grass2 -kd 0.113 0.306 0.008
#The ground
puts "Loading the ground..."
vdisplayobj ground "${folderEnv}/Scene Ground 1.obj"
vdisplayobj tyre "${folderTyre}/tyre_3.4805.obj"
vbsdf tyre -ks 0.3
if { ${isEditLight} == 1 } {
vlight change 0 head 0
vlight change 0 sm 0.02
vlight change 0 color ANTIQUEWHITE
vlight change 0 int 9000
vlight change 0 direction 1 0.2 -1
}
vtextureenv on "${folderEnv}/sky_midafternoon.jpg"
vrenderparams -env on
vclipplane create pln
if { ${isGI} == 1 } {
vrenderparams -ray -gi
vrenderparams -brng
vrenderparams -rayDepth 3
}
# Animation of movement of the camera.
# Prepearing.
proc StartMovementOfCamera {thePts theLocalPts theName} {
vviewparams -scale 0.76084571141153157
vviewparams -proj -0.55490690725196157 0.83079330518538119 0.043137087792445204
vviewparams -up 0.0038687080384806026 -0.049275302086848008 0.99877774189374235
vviewparams -at 904 -0.0925 3.5
vviewparams -eye -1875.1169546272422 4160.7348535943329 219.54166765447638
}
# Main animation.
proc MovementOfCamera {thePts theLocalPts theName} {
global index
global folderVideo
global SamplesPerPixel
if { ${theLocalPts} < 3.0 } {
vshiftcam 0.01
} else {
vshiftcam 0.005
}
puts $index
vrenderparams -spp ${SamplesPerPixel}
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
set index [expr {${index} + 1}]
}
# Animation of rotation of the camera.
# Preparing.
proc StartRotationOfCamera {thePts theLocalPts theName} {
global index
set index 91
vviewparams -scale 0.17291948306641733
vviewparams -proj -0.5549068942726707 0.8307933138774608 0.043137087351443816
vviewparams -up 0 0 1
vviewparams -at 904 -0.0925 3.5
vviewparams -eye 223.11633760908609 1019.310356524007 56.430205481013957
}
# Main animation.
global z
set z 3.5
proc RotationOfCamera {thePts theLocalPts theName} {
global z
global width
global height
global index
global folderVideo
global SamplesPerPixel
puts $index
vmoveto ${width}/2 ${height}/2
#vrotate -0.0349066 0 0
vrotate -0.1396264 0 0
#vrotate 0 -0.004363323 01
vrotate 0 -0.017453292 01
vviewparams -at 904 -0.0925 ${z} -up 0 0 1
vrenderparams -spp ${SamplesPerPixel}
vfps 1
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
set index [expr {${index} + 1}]
set z [expr {${z} - 1.5}]
}
# Animation of deformation of tyre.
# Preparing.
proc StartDeformationOfTyre {thePts theLocalPts theName} {
global index
set index 111
vviewparams -scale 0.70209376404101775
vviewparams -proj 0.29616790541429666 -0.88265982860132486 0.36496054413592205
vviewparams -up -0.11609767165456701 0.34600221479170257 0.9310229846763316
vviewparams -at 904 -0.092499999999972715 -146.5
vviewparams -eye 1269.320051268 -1088.8442787782369 425.17506035310009
#vviewparams -scale 0.68818212755896502
#vviewparams -proj 0.34824854701750618 -0.8177652576045038 0.45823894744470978
#vviewparams -up 0 0 1
#vviewparams -at 904 -0.092499999999972715 -146.5
#vviewparams -eye 1342.2445815876536 -1029.1885184186783 460.15922086382318
}
# Main animation.
proc DeformationOfTyre {thePts theLocalPts theName} {
global index
global folderTyre
global folderVideo
global SamplesPerPixel
global currentTimeTyre
global stepTimeTyre
global endTimeTyre
if { ${currentTimeTyre} <= ${endTimeTyre} } {
#erase previous tyre
vremove tyre
#loading current tyre
puts "loading tyre_3.${currentTimeTyre}..."
vrenderparams -spp 1
vdisplayobj tyre "${folderTyre}/tyre_3.${currentTimeTyre}.obj"
vbsdf tyre -ks 0.3
set bbox [vbounding -print tyre]
regexp {tyre+\n([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+)} ${bbox} full x1 y1 z1 x2 y2 z2
vviewparams -at [expr {($x2 + $x1) * 0.5}] [expr {($y2 + $y1) * 0.5}] -131.5 -up 0 0 1
if { ${currentTimeTyre} <= 4955 } {
vshiftcam 0.01
} elseif { ${currentTimeTyre} < 5300 } {
vshiftcam 0.005
}
vrotate -0.003 0 0
puts $index
vrenderparams -spp ${SamplesPerPixel}
vfps 1
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
vrenderparams -spp 1
set index [expr {$index + 1}]
set currentTimeTyre [expr ${currentTimeTyre} + ${stepTimeTyre}]
}
}
# Rotation of the camera after deformation.
# Preparing.
proc StartRotationOfCameraAfterDeformation {thePts theLocalPts theName} {
global folderTyre
global endTimeTyre
global paveStartKd
global paveStartKt
global index
set index 171
vrenderparams -gi off
vremove tyre
vdisplayobj tyre "${folderTyre}/tyre_3.${endTimeTyre}.obj"
vbsdf tyre -ks 0.3
vrenderparams -gi on
vviewparams -scale 0.89917874503252559
vviewparams -proj 0.12928743010777263 -0.87670185844940729 0.46333423336451535
vviewparams -up -0.066045096204520176 0.45860503872268371 0.88618252280526355
vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
vviewparams -eye 1386.6074883792353 -829.97175321148939 314.75078022962293
#vviewparams -scale 0.9280456841673036
#vviewparams -proj 0.18840463572798008 -0.84034129855590489 0.50826193559776089
#vviewparams -up -0.10946425274888763 0.49633667496588818 0.86120118581777039
#vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
#vviewparams -eye 1437.9007346084109 -769.77670424046596 342.79534506079335
vsetmaterial pave10 glass
vbsdf pave10 -absorpcoeff 1.0 -absorpcolor 1.0 1.0 1.0 -fresnel Constant 0.0 -kt ${paveStartKt} -kd ${paveStartKd}
}
# Main animation.
proc RotationOfCameraAfterDeformation {thePts theLocalPts theName} {
global index
global folderVideo
global SamplesPerPixel
global tyrePlaneCurrentDistance
global tyrePlaneDeltaDistance
puts $index
vrotate 0 0.007853985 0
vclipplane change pln equation -0.1 0.98 0 ${tyrePlaneCurrentDistance}
vclipplane set pln object tyre
set tyrePlaneCurrentDistance [expr {$tyrePlaneCurrentDistance - $tyrePlaneDeltaDistance}]
vrenderparams -spp ${SamplesPerPixel}
vfps 1
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
set index [expr {$index + 1}]
}
# Idle animation.
# Preparing.
proc StartPaveTransparency {thePts theLocalPts theName} {
global folderTyre
global endTimeTyre
global index
global tyrePlaneEndDistance
set index 252
vclipplane change pln equation -0.1 0.98 0 190
vclipplane set pln object tyre
vrenderparams -gi off
vremove tyre
vdisplayobj tyre "${folderTyre}/tyre_3.${endTimeTyre}.obj"
vbsdf tyre -ks 0.3
vrenderparams -gi on
vviewparams -scale 0.89917874503252926
vviewparams -proj 0.14323443575502989 -0.97766449080860029 -0.15380520090653158
vviewparams -up 0.023687355221058894 -0.15197656682365501 0.98810021371272183
vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
vviewparams -eye 1400.0402582973147 -927.21182359687623 -279.63429694048989
#vviewparams -scale 0.92804568416730804
#vviewparams -proj 0.21658311425190047 -0.97083411217050375 -0.10282451685788761
#vviewparams -up 0.023884841470820248 -0.10002361570077746 0.99469834153378234
#vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
#vviewparams -eye 1464.1960761611324 -891.54882551588094 -227.45286659911696
}
# Main animation.
proc PaveTransparency {thePts theLocalPts theName} {
global index
global folderVideo
global paveStartKd
global paveStartKt
global paveCurrentKd
global paveCurrentKt
global paveDeltaKd
global paveDeltaKt
global SamplesPerPixel
puts $index
set paveCurrentKd [expr {$paveCurrentKd - $paveDeltaKd}]
set paveCurrentKt [expr {$paveCurrentKt + $paveDeltaKt}]
vbsdf pave10 -kd ${paveCurrentKd} -kt ${paveCurrentKt}
vrenderparams -spp ${SamplesPerPixel}
vfps 1
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
set index [expr {$index + 1}]
}
# Idle animation.
# Preparing.
proc StartIdleAnim {thePts theLocalPts theName} {
global index
global endTimeTyre
global folderTyre
set index 313
vbsdf pave10 -absorpcoeff 1.0 -absorpcolor 1.0 1.0 1.0 -fresnel Constant 0.0 -kt 1.0 -kd 0.0
vclipplane change pln equation -0.1 0.98 0 190
vclipplane set pln object tyre
vrenderparams -gi off
vremove tyre
vdisplayobj tyre "${folderTyre}/tire_res.obj"
vbsdf tyre -ks 0.3
vrenderparams -gi on
vviewparams -scale 0.89917874503252926
vviewparams -proj 0.14323443575502989 -0.97766449080860029 -0.15380520090653158
vviewparams -up 0.023687358041704527 -0.15197658016980603 0.98810021159237427
vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
vviewparams -eye 1400.0402582973147 -927.21182359687623 -279.63429694048989
#vviewparams -scale 0.92804568416730826
#vviewparams -proj 0.21658311425190027 -0.97083411217050386 -0.10282451685788763
#vviewparams -up 0.023884838973521033 -0.10002359984931483 0.99469834318771899
#vviewparams -at 1262.0869750976562 14.405502319335938 -131.5
#vviewparams -eye 1464.1960761611322 -891.54882551588094 -227.45286659911696
}
# Main idle animation.
proc IdleAnim {thePts theLocalPts theName} {
global index
global folderVideo
global SamplesPerPixel
puts $index
vrenderparams -spp ${SamplesPerPixel}
vdump "${folderVideo}/Res_${index}.png"
vrenderparams -spp 1
set index [expr {$index + 1}]
}
if { ${isAnim} == 1 } {
set startTimeMovCam 0.0
set endTimeMovCam 4.5
set endTimeRotation 4.8
set endTimeDeformations 8.0
vlight change 0 head 0
vrenderparams -spp 1
vanim movcam -reset -onRedraw MovementOfCamera -onStart StartMovementOfCamera
vanim animcam0 -reset -addSlice 0.0 4.5 movcam
#vanim -play animcam0 -playFps 20
vanim rotcam -reset -onRedraw RotationOfCamera -onStart StartRotationOfCamera
vanim animcam1 -reset -addSlice 0.0 1.0 rotcam
#vanim -play animcam1 -playFps 20
vanim deftyre -reset -onRedraw DeformationOfTyre -onStart StartDeformationOfTyre
vanim animdef -reset -addSlice 0.0 3.0 deftyre
#vanim -play animdef -playFps 20
vanim rotCamAfterDef -reset -onRedraw RotationOfCameraAfterDeformation -onStart StartRotationOfCameraAfterDeformation
vanim animRotCamAfterDef -reset -addSlice 0.0 4.0 rotCamAfterDef
vanim -play animRotCamAfterDef -playFps 20
vanim pavetrans -reset -onRedraw PaveTransparency -onStart StartPaveTransparency
vanim animpavetrans -reset -addSlice 0.0 3.0 pavetrans
vanim -play animpavetrans -playFps 20
vanim idle -reset -onRedraw IdleAnim -onStart StartIdleAnim
vanim animidle -reset -addSlice 0.0 2.0 idle
vanim -play animidle -playFps 20
vrenderparams -spp 1
}

View File

@@ -160,7 +160,6 @@ Graphic3d_TypeOfReflection.hxx
Graphic3d_TypeOfShaderObject.hxx
Graphic3d_TypeOfShadingModel.hxx
Graphic3d_TypeOfStructure.hxx
Graphic3d_TypeOfSurfaceDetail.hxx
Graphic3d_TypeOfTexture.hxx
Graphic3d_TypeOfTextureFilter.hxx
Graphic3d_TypeOfTextureMode.hxx

View File

@@ -54,7 +54,7 @@ public:
}
//! Pass clip planes to the associated graphic driver structure
void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; }
virtual void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; }
//! @return bounding box of this presentation
const Graphic3d_BndBox4f& BoundingBox() const

View File

@@ -1068,7 +1068,6 @@ void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
SetTextureEnv (theOther->TextureEnv());
SetCullingEnabled (theOther->IsCullingEnabled());
SetShadingModel (theOther->ShadingModel());
SetSurfaceDetailType (theOther->SurfaceDetailType());
SetBackfacingModel (theOther->BackfacingModel());
SetCamera (new Graphic3d_Camera (theOther->Camera()));
SetBackZClippingOn (theOther->BackZClippingIsOn());

View File

@@ -40,7 +40,6 @@
#include <Graphic3d_TypeOfAnswer.hxx>
#include <Graphic3d_TypeOfBackfacingModel.hxx>
#include <Graphic3d_TypeOfShadingModel.hxx>
#include <Graphic3d_TypeOfSurfaceDetail.hxx>
#include <Graphic3d_TypeOfVisualization.hxx>
#include <Graphic3d_Vec3.hxx>
#include <Graphic3d_ZLayerId.hxx>
@@ -434,12 +433,6 @@ public:
//! Sets shading model of the view.
virtual void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel) = 0;
//! Returns surface detail type of the view.
virtual Graphic3d_TypeOfSurfaceDetail SurfaceDetailType() const = 0;
//! Sets surface detail type of the view.
virtual void SetSurfaceDetailType (const Graphic3d_TypeOfSurfaceDetail theType) = 0;
//! Return backfacing model used for the view.
virtual Graphic3d_TypeOfBackfacingModel BackfacingModel() const = 0;

View File

@@ -61,6 +61,8 @@ public:
IsTransparentShadowEnabled (Standard_False),
UseEnvironmentMapBackground (Standard_False),
CoherentPathTracingMode (Standard_False),
IsGIFilteringEnabled (Standard_False),
RadianceClampValue (10.0),
// stereoscopic parameters
StereoMode (Graphic3d_StereoMode_QuadBuffer),
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
@@ -99,6 +101,8 @@ public:
Standard_Boolean IsTransparentShadowEnabled; //!< enables/disables light propagation through transparent media, False by default
Standard_Boolean UseEnvironmentMapBackground; //!< enables/disables environment map background
Standard_Boolean CoherentPathTracingMode; //!< enables/disables 'coherent' tracing mode (single RNG seed within 16x16 image blocks)
Standard_Boolean IsGIFilteringEnabled; //!< enables/disables post-processing of GI rendering results
Standard_Real RadianceClampValue; //!< maximum radiance value which will not be clamped.
Graphic3d_StereoMode StereoMode; //!< stereoscopic output mode, Graphic3d_StereoMode_QuadBuffer by default
Anaglyph AnaglyphFilter; //!< filter for anaglyph output, Anaglyph_RedCyan_Optimized by default

View File

@@ -1,32 +0,0 @@
// Created on: 1991-10-07
// Created by: NW,JPB,CAL
// Copyright (c) 1991-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.
#ifndef _Graphic3d_TypeOfSurfaceDetail_HeaderFile
#define _Graphic3d_TypeOfSurfaceDetail_HeaderFile
//! Modes of visualisation of objects in a view
//!
//! TOD_NONE no texture mapping
//! TOD_ENVIRONMENT only environnement mapping
//! TOD_ALL environnement + texture mapping
enum Graphic3d_TypeOfSurfaceDetail
{
Graphic3d_TOD_NONE,
Graphic3d_TOD_ENVIRONMENT,
Graphic3d_TOD_ALL
};
#endif // _Graphic3d_TypeOfSurfaceDetail_HeaderFile

View File

@@ -35,7 +35,8 @@ struct Graphic3d_ZLayerSettings
Flags (Graphic3d_ZLayerDepthTest
| Graphic3d_ZLayerDepthWrite
| Graphic3d_ZLayerDepthClear),
IsImmediate (false)
IsImmediate (false),
UseEnvironmentTexture (true)
{}
//! Returns true if theSetting is enabled.
@@ -76,10 +77,11 @@ struct Graphic3d_ZLayerSettings
public:
Standard_ShortReal DepthOffsetFactor; //!< factor argument value for OpenGl glPolygonOffset function
Standard_ShortReal DepthOffsetUnits; //!< units argument value for OpenGl glPolygonOffset function
Standard_Integer Flags; //!< storage field for settings
bool IsImmediate; //!< immediate layer will be drawn after all normal layers
Standard_ShortReal DepthOffsetFactor; //!< factor argument value for OpenGl glPolygonOffset function
Standard_ShortReal DepthOffsetUnits; //!< units argument value for OpenGl glPolygonOffset function
Standard_Integer Flags; //!< storage field for settings
bool IsImmediate; //!< immediate layer will be drawn after all normal layers
bool UseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
};

View File

@@ -0,0 +1,16 @@
#include <CafShapePrs.h>
IMPLEMENT_STANDARD_RTTIEXT(CafShapePrs, XCAFPrs_AISObject)
// =======================================================================
// function : CafShapePrs
// purpose :
// =======================================================================
CafShapePrs::CafShapePrs (const TDF_Label& theLabel,
const XCAFPrs_Style& theStyle,
const Graphic3d_MaterialAspect& theMaterial)
: XCAFPrs_AISObject (theLabel),
myDefStyle (theStyle)
{
SetMaterial (theMaterial);
}

62
src/MeshVS/CafShapePrs.h Normal file
View File

@@ -0,0 +1,62 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef CafShapePrs_Header
#define CafShapePrs_Header
#include <XCAFPrs_AISObject.hxx>
#include <XCAFPrs_Style.hxx>
typedef NCollection_DataMap<TopoDS_Shape, Handle(AIS_ColoredDrawer), TopTools_ShapeMapHasher> CafDataMapOfShapeColor;
//! Interactive object for shape in DECAF document.
class CafShapePrs : public XCAFPrs_AISObject
{
public:
//! Default constructor.
Standard_EXPORT CafShapePrs (const TDF_Label& theLabel,
const XCAFPrs_Style& theStyle,
const Graphic3d_MaterialAspect& theMaterial);
//! Search custom aspect for specified shape.
Standard_Boolean FindCustomAspects (const TopoDS_Shape& theShape,
Handle(AIS_ColoredDrawer)& theAspects) const
{
return myShapeColors.Find (theShape, theAspects);
}
//! Access the styles map.
const CafDataMapOfShapeColor& ShapeColors() const { return myShapeColors; }
//! Override default style.
virtual void DefaultStyle (XCAFPrs_Style& theStyle) const Standard_OVERRIDE
{
theStyle = myDefStyle;
}
protected:
XCAFPrs_Style myDefStyle; //!< default style
public: //! @name Declaration of CASCADE RTTI
DEFINE_STANDARD_RTTIEXT(CafShapePrs, XCAFPrs_AISObject)
};
DEFINE_STANDARD_HANDLE (CafShapePrs, XCAFPrs_AISObject)
#endif

View File

@@ -84,3 +84,19 @@ MeshVS_TwoNodes.hxx
MeshVS_TwoNodesHasher.hxx
MeshVS_VectorPrsBuilder.cxx
MeshVS_VectorPrsBuilder.hxx
MeshDataSource.h
MeshDataSource.cpp
ObjDataSource.h
ObjDataSource.cpp
MeshScalarProperty.h
MeshPresentation.h
MeshPresentation.cpp
MeshPrsBuilder.h
MeshPrsBuilder.cpp
ObjDataWriter.h
ObjDataWriter.cpp
FaceIterator.h
FaceIterator.cpp
CafShapePrs.h
CafShapePrs.cpp

150
src/MeshVS/FaceIterator.cpp Normal file
View File

@@ -0,0 +1,150 @@
// 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 <FaceIterator.h>
#include <AIS_ColoredShape.hxx>
#include <AIS_ConnectedInteractive.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepLProp_SLProps.hxx>
#include <BRep_Tool.hxx>
#include <CafShapePrs.h>
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_Triangulation.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
// =======================================================================
// function : FaceIterator
// purpose :
// =======================================================================
FaceIterator::FaceIterator (const AIS_ListOfInteractive& thePrsList)
: myPrsIter (thePrsList)
{
Next();
}
// =======================================================================
// function : Next
// purpose :
// =======================================================================
void FaceIterator::Next()
{
for (; myPrsIter.More(); myPrsIter.Next())
{
Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (myPrsIter.Value());
Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (!aConnected.IsNull() ? aConnected->ConnectedTo() : myPrsIter.Value());
ShapePrs = Handle(CafShapePrs)::DownCast (aShapePrs);
myPrsLocation = TopLoc_Location();
if (ShapePrs.IsNull())
{
Triangulation.Nullify();
Face.Nullify();
myFacesMap.Clear();
continue;
}
else if (!aConnected.IsNull()
&& aConnected->LocalTransformation().Form() != gp_Identity)
{
myPrsLocation = TopLoc_Location (aConnected->LocalTransformation());
}
TopoDS_Shape aShape = ShapePrs->Shape();
if (aShape.IsNull())
{
Triangulation.Nullify();
Face.Nullify();
myFacesMap.Clear();
continue;
}
if (myFacesMap.IsEmpty())
{
// should be replaced by TopTools_OrientedShapeMaphasher to export correctly composed solids
// (e.g. shared face should be exported twice with different order of triangles
// and possible unique color)
TopExp::MapShapesAndAncestors (aShape, TopAbs_FACE, TopAbs_SHAPE, myFacesMap);
if (myFacesMap.IsEmpty())
{
Triangulation.Nullify();
Face.Nullify();
continue;
}
// register compounds generated by XCAFPrs_AISObject for grouping elements with the same style
const CafDataMapOfShapeColor& aColorsMap = ShapePrs->ShapeColors();
for (CafDataMapOfShapeColor::Iterator aShapeMapIter (aColorsMap); aShapeMapIter.More(); aShapeMapIter.Next())
{
if (aShapeMapIter.Key().ShapeType() != TopAbs_COMPOUND
|| aShapeMapIter.Key().IsEqual (aShape))
{
continue;
}
for (TopExp_Explorer aCompFaceIter (aShapeMapIter.Key(), TopAbs_FACE); aCompFaceIter.More(); aCompFaceIter.Next())
{
const Standard_Integer anIndex = myFacesMap.FindIndex (aCompFaceIter.Current());
if (anIndex != 0)
{
myFacesMap.ChangeFromIndex (anIndex).Append (aShapeMapIter.Key());
}
}
}
myFaceIter = TopTools_IndexedDataMapOfShapeListOfShape::Iterator (myFacesMap);
}
for (; myFaceIter.More(); myFaceIter.Next())
{
Face = TopoDS::Face (myFaceIter.Key());
Triangulation = BRep_Tool::Triangulation (Face, myFaceLocation);
Trsf = myPrsLocation.Multiplied (myFaceLocation).Transformation();
if ( Triangulation.IsNull()
|| Triangulation->Triangles().Length() == 0
|| !Triangulation->HasUVNodes())
{
continue;
}
Handle(AIS_ColoredDrawer) aCustomDrawer;
if (!ShapePrs->FindCustomAspects (Face, aCustomDrawer))
{
for (TopTools_ListOfShape::Iterator aParentIter (myFaceIter.Value()); aParentIter.More(); aParentIter.Next())
{
if (ShapePrs->FindCustomAspects (aParentIter.Value(), aCustomDrawer))
{
break;
}
}
if (aCustomDrawer.IsNull())
{
ShapePrs->FindCustomAspects (aShape, aCustomDrawer);
}
}
Drawer = aCustomDrawer;
if (Drawer.IsNull())
{
Drawer = aShapePrs->Attributes();
}
myFaceIter.Next();
return;
}
Triangulation.Nullify();
Face.Nullify();
myFacesMap.Clear();
myFaceIter = TopTools_IndexedDataMapOfShapeListOfShape::Iterator();
Drawer.Nullify();
}
}

64
src/MeshVS/FaceIterator.h Normal file
View File

@@ -0,0 +1,64 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef FaceIterator_H
#define FaceIterator_H
#include <AIS_ListOfInteractive.hxx>
#include <gp_Trsf.hxx>
#include <TopoDS_Face.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
class CafShapePrs;
class Prs3d_Drawer;
class Poly_Triangulation;
//! Auxiliary class to iterate through triangulated faces in presentations list.
class FaceIterator
{
public:
Handle(CafShapePrs) ShapePrs;
TopoDS_Face Face;
Handle(Prs3d_Drawer) Drawer;
Handle(Poly_Triangulation) Triangulation;
gp_Trsf Trsf;
public:
//! Main constructor.
Standard_EXPORT FaceIterator (const AIS_ListOfInteractive& thePrsList);
//! Return true if iterator points to the valid triangulation.
bool More() const
{
return !Triangulation.IsNull();
}
//! Find next value.
Standard_EXPORT void Next();
private:
AIS_ListOfInteractive::Iterator myPrsIter;
TopLoc_Location myPrsLocation;
TopTools_IndexedDataMapOfShapeListOfShape myFacesMap;
TopTools_IndexedDataMapOfShapeListOfShape::Iterator myFaceIter;
TopLoc_Location myFaceLocation;
};
#endif // FaceIterator_H

View File

@@ -0,0 +1,278 @@
// Copyright (c) 2014-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 <MeshDataSource.h>
#include <Standard_CLocaleSentry.hxx>
#include <MeshVS_Drawer.hxx>
#include <MeshVS_DrawerAttribute.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressSentry.hxx>
#include <NCollection_Handle.hxx>
#include <TColgp_SequenceOfXYZ.hxx>
#include <TColStd_DataMapOfIntegerReal.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Quantity_Color.hxx>
IMPLEMENT_STANDARD_RTTIEXT(MeshScalarProperty, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(MeshDataSource, MeshVS_DataSource)
//================================================================
// Function : Constructor
// Purpose :
//================================================================
MeshDataSource::MeshDataSource()
{
//
}
//================================================================
// Function : Clear
// Purpose :
//================================================================
void MeshDataSource::Clear()
{
myUsedNodes.Clear();
myFreeNodes.Clear();
myUsedElements.Clear();
myComments.Clear();
myNodes.Clear();
myNormals.Clear();
myNodesUV.Clear();
myNodalColors.Clear();
myElements.Clear();
myNodalQuantities.Clear();
myElementalQuantities.Clear();
myGroups.Clear();
}
//================================================================
// Function : GetGeom
// Purpose :
//================================================================
Standard_Boolean MeshDataSource::GetGeom (const Standard_Integer theID,
const Standard_Boolean theIsElement,
TColStd_Array1OfReal& theCoords,
Standard_Integer& theNbNodes,
MeshVS_EntityType& theType) const
{
const Standard_Integer aLow = theCoords.Lower();
if (theIsElement)
{
if (theID < 0 || theID >= myUsedElements.Extent())
{
return Standard_False;
}
const Graphic3d_Vec4i& anElem = myElements.Value (theID);
theType = MeshVS_ET_Face;
theNbNodes = anElem[3] == -1 ? 3 : 4;
for (Standard_Integer aNodeIter = 0, aCoordIter = aLow - 1; aNodeIter < theNbNodes; ++aNodeIter)
{
const Graphic3d_Vec3& aNode = myNodes.Value (anElem[aNodeIter]);
theCoords (++aCoordIter) = aNode.x();
theCoords (++aCoordIter) = aNode.y();
theCoords (++aCoordIter) = aNode.z();
}
return Standard_True;
}
else if (theID < 0 || theID >= myUsedNodes.Extent())
{
return Standard_False;
}
theType = MeshVS_ET_Node;
theNbNodes = 1;
const Graphic3d_Vec3& aNode = myNodes.Value (theID);
theCoords (aLow) = aNode.x();
theCoords (aLow + 1) = aNode.y();
theCoords (aLow + 2) = aNode.z();
return Standard_True;
}
//================================================================
// Function : GetNodesByElement
// Purpose :
//================================================================
Standard_Boolean MeshDataSource::GetNodesByElement (const Standard_Integer theID,
TColStd_Array1OfInteger& theNodeIDs,
Standard_Integer& theNbNodes) const
{
if (theID < 0 || theID >= myUsedElements.Extent())
{
return Standard_False;
}
const Graphic3d_Vec4i& anElem = myElements.Value (theID);
theNbNodes = anElem[3] == -1 ? 3 : 4;
if (theNodeIDs.Length() < theNbNodes)
{
return Standard_False;
}
const Standard_Integer aLow = theNodeIDs.Lower();
theNodeIDs (aLow) = anElem[0];
theNodeIDs (aLow + 1) = anElem[1];
theNodeIDs (aLow + 2) = anElem[2];
if (theNbNodes == 4)
{
theNodeIDs (aLow + 3) = anElem[3];
}
return Standard_True;
}
//================================================================
// Function : GetNodeNormal
// Purpose :
//================================================================
Standard_Boolean MeshDataSource::GetNodeNormal (const Standard_Integer theRankNode,
const Standard_Integer theElementId,
Standard_Real& theNX,
Standard_Real& theNY,
Standard_Real& theNZ) const
{
if (theElementId < 0 || theElementId >= myUsedElements.Extent()
|| !HasNormals())
{
return Standard_False;
}
const Graphic3d_Vec4i& anElem = myElements.Value (theElementId);
const Graphic3d_Vec3& aNorm = myNormals.Value (anElem[theRankNode - 1]);
theNX = Standard_Real(aNorm.x());
theNY = Standard_Real(aNorm.y());
theNZ = Standard_Real(aNorm.z());
return Standard_True;
}
inline void truncateToRange (Standard_Real& theValue,
const Standard_Real theLower,
const Standard_Real theUpper)
{
if (theValue <= theLower)
{
theValue = theLower;
}
else if (theValue >= theUpper)
{
theValue = theUpper;
}
}
//================================================================
// Function : FillPropertyBuilder
// Purpose :
//================================================================
void MeshDataSource::FillPropertyBuilder (const Handle(MeshVS_PrsBuilder)& theBuilder,
const Handle(MeshScalarProperty)& theProperty) const
{
Handle(MeshVS_NodalColorPrsBuilder) aNodalBuilder = Handle(MeshVS_NodalColorPrsBuilder) ::DownCast (theBuilder);
Handle(MeshVS_ElementalColorPrsBuilder) anElemBuilder = Handle(MeshVS_ElementalColorPrsBuilder)::DownCast (theBuilder);
if ((aNodalBuilder.IsNull() && anElemBuilder.IsNull())
|| theProperty.IsNull())
{
return;
}
//theBuilder->UseTexture (Standard_True);
const Standard_Boolean isGrayscale = (theProperty->Name() == "intensity");
const Standard_Real aLowerValue = isGrayscale ? 0.0 : theProperty->LowerValue();
const Standard_Real aRange = isGrayscale ? 1.0 : theProperty->UpperValue() - theProperty->LowerValue();
const Graphic3d_Vec3d aScale00 = isGrayscale ? Graphic3d_Vec3d (0.0, 0.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
const Graphic3d_Vec3d aScale05 = isGrayscale ? Graphic3d_Vec3d (0.5, 0.5, 0.5) : Graphic3d_Vec3d (0.0, 1.0, 0.0);
const Graphic3d_Vec3d aScale10 = isGrayscale ? Graphic3d_Vec3d (1.0, 1.0, 1.0) : Graphic3d_Vec3d (1.0, 0.0, 0.0);
Graphic3d_Vec3d aColor;
for (Standard_Integer anElemIter = theProperty->LowerIndex(); anElemIter <= theProperty->UpperIndex(); ++anElemIter)
{
if (aRange <= Precision::Confusion())
{
aColor = aScale00;
}
else
{
Standard_Real aValue = (theProperty->Value (anElemIter) - aLowerValue) / aRange;
if (aValue < 0.5)
{
aValue *= 2.0;
aColor = aScale00 * (1.0 - aValue) + aScale05 * aValue;
}
else
{
aValue = (aValue - 0.5) * 2.0;
aColor = aScale05 * (1.0 - aValue) + aScale10 * aValue;
}
truncateToRange (aColor.r(), 0.0, 1.0);
truncateToRange (aColor.g(), 0.0, 1.0);
truncateToRange (aColor.b(), 0.0, 1.0);
}
const Quantity_Color aQColor (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
if (!aNodalBuilder.IsNull())
{
aNodalBuilder->SetColor (anElemIter, aQColor);
}
else
{
anElemBuilder->SetColor1 (anElemIter, aQColor);
}
}
}
//================================================================
// Function : FillNodalColorsBuilder
// Purpose :
//================================================================
void MeshDataSource::FillNodalColorsBuilder (const Handle(MeshVS_NodalColorPrsBuilder)& theBuilder) const
{
if (theBuilder.IsNull()
|| !HasNodalColors())
{
return;
}
for (Standard_Integer aNodeIter = myNodalColors.Lower(); aNodeIter <= myNodalColors.Upper(); ++aNodeIter)
{
const Graphic3d_Vec4ub& aColor = myNodalColors.Value (aNodeIter);
const Quantity_Color aQColor (aColor.r() / 255.0, aColor.g() / 255.0, aColor.b() / 255.0, Quantity_TOC_RGB);
theBuilder->SetColor (aNodeIter, aQColor);
}
}
//================================================================
// Function : NbElements
// Purpose :
//================================================================
void MeshDataSource::NbElements (Standard_Integer& theNbTris,
Standard_Integer& theNbQuads) const
{
for (NCollection_Vector<Graphic3d_Vec4i>::Iterator anElemIter (myElements); anElemIter.More(); anElemIter.Next())
{
const Graphic3d_Vec4i& anElem = anElemIter.Value();
if (anElem[3] == -1)
{
++theNbTris;
}
else
{
++theNbQuads;
}
}
}

304
src/MeshVS/MeshDataSource.h Normal file
View File

@@ -0,0 +1,304 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef MeshDataSource_H
#define MeshDataSource_H
#include <MeshScalarProperty.h>
#include <MeshVS_DataSource.hxx>
#include <MeshVS_EntityType.hxx>
#include <MeshVS_ElementalColorPrsBuilder.hxx>
#include <MeshVS_NodalColorPrsBuilder.hxx>
#include <MeshVS_PrsBuilder.hxx>
#include <Message_ProgressIndicator.hxx>
#include <NCollection_DataMap.hxx>
#include <TColStd_HArray2OfInteger.hxx>
#include <TColStd_HArray2OfReal.hxx>
#if defined(_WIN32)
#define ftell64(a) _ftelli64(a)
#define fseek64(a,b,c) _fseeki64(a,b,c)
#else
#define ftell64(a) ftello(a)
#define fseek64(a,b,c) fseeko(a,b,c)
#endif
//! Material definition.
struct MeshMaterial
{
Graphic3d_MaterialAspect Aspect;
TCollection_AsciiString Texture;
};
//! Mesh sub-group definition
struct MeshGroup
{
TCollection_AsciiString Name; //!< group name
Standard_Integer NodeLower; //!< index of lower Vertex
Standard_Integer NodeUpper; //!< index of upper Vertex
Standard_Integer ElemLower; //!< index of lower Element
Standard_Integer ElemUpper; //!< index of upper Element
MeshMaterial Material; //!< associated material
MeshGroup() : NodeLower (-1), NodeUpper (-1), ElemLower (-1), ElemUpper (-1) {}
};
//! The DataSource for working with mesh data.
class MeshDataSource : public MeshVS_DataSource
{
public:
//! Empty constructor.
Standard_EXPORT MeshDataSource();
//! Clear mesh structure.
Standard_EXPORT void Clear();
//! Read the mesh from specified file.
virtual Standard_Boolean Read (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress = NULL,
const Standard_Integer theIndexLimit = -1,
const Standard_Integer theMemoryLimitMiB = -1) = 0;
//! Returns geometry information about node or element by co-ordinates.
//! For element this method must return all its nodes co-ordinates in the strict order: X, Y, Z and
//! with nodes order is the same as in wire bounding the face or link.
//! @param theIsElement flag to retrieve information about Element or Node
//! @param theNbNodes number of nodes of element, it is recommended to return 1 for node
//! @param theType element type
Standard_EXPORT virtual Standard_Boolean GetGeom (const Standard_Integer theID,
const Standard_Boolean theIsElement,
TColStd_Array1OfReal& theCoords,
Standard_Integer& theNbNodes,
MeshVS_EntityType& theType) const Standard_OVERRIDE;
//! This method is similar to GetGeom, but returns only element or node type.
virtual Standard_Boolean GetGeomType (const Standard_Integer /*theID*/,
const Standard_Boolean theIsElement,
MeshVS_EntityType& theType) const Standard_OVERRIDE
{
theType = theIsElement ? MeshVS_ET_Face : MeshVS_ET_Node;
return Standard_True;
}
//! Return pointer which represents element or node data structure.
virtual Standard_Address GetAddr (const Standard_Integer /*theID*/,
const Standard_Boolean /*theIsElement*/) const Standard_OVERRIDE { return NULL; }
//! This method returns information about what node this element consist of.
Standard_EXPORT virtual Standard_Boolean GetNodesByElement (const Standard_Integer theID,
TColStd_Array1OfInteger& theNodeIDs,
Standard_Integer& theNbNodes) const Standard_OVERRIDE;
//! This method returns map of all nodes the object consist of.
virtual const TColStd_PackedMapOfInteger& GetAllNodes() const Standard_OVERRIDE { return myFreeNodes; }
//! This method returns map of all elements the object consist of.
virtual const TColStd_PackedMapOfInteger& GetAllElements() const Standard_OVERRIDE { return myUsedElements; }
//! This method return normal of node ranknode of face Id,
//! which is using for smooth shading presentation.
//! Returns false if normal isn't defined.
Standard_EXPORT virtual Standard_Boolean GetNodeNormal (const Standard_Integer theRankNode,
const Standard_Integer theElementId,
Standard_Real& theNX,
Standard_Real& theNY,
Standard_Real& theNZ) const Standard_OVERRIDE;
public:
//! Return file comments.
const NCollection_Sequence<TCollection_AsciiString>& FileComments() const
{
return myComments;
}
//! Return list of sub-groups with materials.
const NCollection_Vector<MeshGroup>& Groups() { return myGroups; }
//! Return overall nodes number.
Standard_Integer NbNodes() const { return myNodes.Length(); }
//! Return vector of nodes.
const NCollection_Vector<Graphic3d_Vec3>& Nodes() const { return myNodes; }
//! Return overall elements number.
Standard_Integer NbElements() const { return myElements.Length(); }
//! Determine elements number.
Standard_EXPORT void NbElements (Standard_Integer& theNbTris,
Standard_Integer& theNbQuads) const;
//! Return vector of elements.
const NCollection_Vector<Graphic3d_Vec4i>& Elements() const { return myElements; }
//! Return per-node scalar properties.
const MeshScalarProperties& NodalQuantities() const { return myNodalQuantities; }
//! Return per-element scalar properties.
const MeshScalarProperties& ElementalQuantities() const { return myElementalQuantities; }
//! Return true if per-node colors have been assigned
Standard_Boolean HasNodalColors() const
{
return myNodalColors.Length() == myNodes.Length()
&& !myNodalColors.IsEmpty();
}
//! Return vector of nodal colors (optional).
const NCollection_Vector<Graphic3d_Vec4ub>& NodalColors() const { return myNodalColors; }
//! Return true if per-node normals have been assigned
Standard_Boolean HasNormals() const
{
return myNormals.Length() == myNodes.Length()
&& !myNormals.IsEmpty();
}
//! Return vector of nodal normals (optional).
const NCollection_Vector<Graphic3d_Vec3>& Normals() const { return myNormals; }
//! Return true if per-node UV parameters have been assigned
Standard_Boolean HasUV() const
{
return myNodesUV.Length() == myNodes.Length()
&& !myNodesUV.IsEmpty();
}
//! Return vector of nodal UV parameters (optional).
const NCollection_Vector<Graphic3d_Vec2>& NodesUV() const { return myNodesUV; }
//! Return true if texture has been assigned.
Standard_Boolean HasTexture() const
{
Standard_Integer aTextureCount = 0;
for (auto anIter = myGroups.cbegin(); anIter != myGroups.cend(); ++anIter)
{
aTextureCount += (anIter->Material.Texture.IsEmpty()) ? 0 : 1;
}
return !myGroups.IsEmpty()
//&& !myGroups.First().Material.Texture.IsEmpty()
&& aTextureCount
&& HasUV();
}
//! Return assigned texture.
TCollection_AsciiString Texture() const
{
return HasTexture() ? myGroups.First().Material.Texture : "";
}
public:
//! Fill-in nodal (MeshVS_NodalColorPrsBuilder) or elemental (MeshVS_ElementalColorPrsBuilder) builder.
Standard_EXPORT void FillPropertyBuilder (const Handle(MeshVS_PrsBuilder)& theBuilder,
const Handle(MeshScalarProperty)& theProperty) const;
//! Fill-in nodal (MeshVS_NodalColorPrsBuilder) builder by colors.
Standard_EXPORT void FillNodalColorsBuilder (const Handle(MeshVS_NodalColorPrsBuilder)& theBuilder) const;
public:
//! Append new vertex.
void AddNodePosition (const Graphic3d_Vec3& thePosition)
{
myNodes.Append (thePosition);
myUsedNodes.Add (myNodes.Upper());
}
//! Append new vertex.
void AddNodePosition (const gp_XYZ& thePosition)
{
myNodes.Append (Graphic3d_Vec3 ((float )thePosition.X(),
(float )thePosition.Y(),
(float )thePosition.Z()));
myUsedNodes.Add (myNodes.Upper());
}
//! Append new normal.
void AddNodeNormal (const Graphic3d_Vec3& theNormal)
{
myNormals.Append (theNormal);
}
//! Append new normal.
void AddNodeNormal (const gp_XYZ& theNormal)
{
myNormals.Append (Graphic3d_Vec3 ((float )theNormal.X(),
(float )theNormal.Y(),
(float )theNormal.Z()));
}
//! Append new UV parameters pair.
void AddNodeUV (const Graphic3d_Vec2& theUV)
{
myNodesUV.Append (theUV);
}
//! Append new color.
void AddNodeColor (const Graphic3d_Vec4ub& theColor)
{
myNodalColors.Append (theColor);
}
//! Append node property.
void AddNodeProperty (const Standard_Integer thePropIndex,
const Standard_Real theValue)
{
myNodalQuantities.ChangeValue (thePropIndex)->AppendValue (theValue);
}
//! Append new element.
void AddElement (const Graphic3d_Vec4i& theNodeIndices)
{
myElements.Append (theNodeIndices);
myUsedElements.Add (myElements.Upper());
}
//! Append element property.
void AddElementProperty (const Standard_Integer thePropIndex,
const Standard_Real theValue)
{
myElementalQuantities.ChangeValue (thePropIndex)->AppendValue (theValue);
}
protected:
TColStd_PackedMapOfInteger myUsedNodes; //!< used node indices
TColStd_PackedMapOfInteger myFreeNodes; //!< indices of free nodes
TColStd_PackedMapOfInteger myUsedElements; //!< used element indices
NCollection_Sequence<TCollection_AsciiString>
myComments; //!< file comments
NCollection_Vector<Graphic3d_Vec3> myNodes; //!< vector of nodes
NCollection_Vector<Graphic3d_Vec3> myNormals; //!< vector of nodal normals (optional)
NCollection_Vector<Graphic3d_Vec2> myNodesUV; //!< vector of UV nodes (optional)
NCollection_Vector<Graphic3d_Vec4ub> myNodalColors; //!< vector of nodal colors (optional)
NCollection_Vector<Graphic3d_Vec4i> myElements; //!< vector of elements
MeshScalarProperties myNodalQuantities; //!< per-node scalar quantities
MeshScalarProperties myElementalQuantities; //!< per-element scalar quantities
NCollection_Vector<MeshGroup> myGroups; //!< sub-groups with materials
public:
DEFINE_STANDARD_RTTIEXT(MeshDataSource, MeshVS_DataSource)
};
DEFINE_STANDARD_HANDLE(MeshDataSource, MeshVS_DataSource)
#endif // MeshDataSource_H

View File

@@ -0,0 +1,137 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#include "MeshPresentation.h"
#include <MeshVS_Drawer.hxx>
#include <MeshVS_DrawerAttribute.hxx>
#include <MeshVS_Tool.hxx>
IMPLEMENT_STANDARD_RTTIEXT(MeshPresentation, MeshVS_Mesh)
// =======================================================================
// function : MeshPresentation
// purpose :
// =======================================================================
MeshPresentation::MeshPresentation()
{}
// =======================================================================
// function : SetMaterial
// purpose :
// =======================================================================
void MeshPresentation::SetMaterial (const Graphic3d_MaterialAspect& theMat)
{
Handle(MeshVS_Drawer) aDrawer = GetDrawer();
if (aDrawer.IsNull())
{
return;
}
aDrawer->SetMaterial (MeshVS_DA_FrontMaterial, theMat);
aDrawer->SetMaterial (MeshVS_DA_BackMaterial, theMat);
Standard_Boolean hasReflection = Standard_True;
aDrawer->GetBoolean (MeshVS_DA_Reflection, hasReflection);
Graphic3d_MaterialAspect aMat = theMat;
if (!hasReflection)
{
aMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
aMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
aMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
aMat.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
}
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = MeshVS_Tool::CreateAspectFillArea3d (aDrawer, aMat);
Handle(Graphic3d_AspectLine3d) anOldLineAsp = new Graphic3d_AspectLine3d();
Handle(Graphic3d_AspectText3d) anOldTextAsp = new Graphic3d_AspectText3d();
Handle(Graphic3d_AspectMarker3d) anOldPntAsp = new Graphic3d_AspectMarker3d();
Handle(Graphic3d_AspectFillArea3d) anOldAreaAps = new Graphic3d_AspectFillArea3d();
const PrsMgr_Presentations& aPrsList = Presentations();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() == MeshVS_DMF_WireFrame
|| aPrsModed.Mode() == MeshVS_DMF_NodalColorDataPrs
|| aPrsModed.Mode() == MeshVS_DMF_ElementalColorDataPrs)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
if (!aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
continue;
}
aGroup->GroupPrimitivesAspect (anOldLineAsp, anOldTextAsp, anOldPntAsp, anOldAreaAps);
anAreaAsp->SetTextureMap (anOldAreaAps->TextureMap());
if (anOldAreaAps->TextureMapState())
{
anAreaAsp->SetTextureMapOn();
}
else
{
anAreaAsp->SetTextureMapOff();
}
aGroup->SetGroupPrimitivesAspect (anAreaAsp);
}
}
}
// =======================================================================
// function : SetClosed
// purpose :
// =======================================================================
void MeshPresentation::SetClosed (const bool theIsClosed)
{
const PrsMgr_Presentations& aPrsList = Presentations();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() == MeshVS_DMF_WireFrame
|| aPrsModed.Mode() == MeshVS_DMF_Shrink)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetClosed (theIsClosed);
}
}
}
}
// =======================================================================
// function : SetClosed
// purpose :
// =======================================================================
void MeshPresentation::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode)
{
MeshVS_Mesh::Compute (thePrsMgr, thePrs, theMode);
// mark mesh as closed without checks for Capping algorithm but without suppressing back faces,
// thus artifacts on shells will appear only with capping option turned on and not in normal mode
SetClosed (true);
}

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef MeshPresentation_H
#define MeshPresentation_H
#include <MeshVS_Mesh.hxx>
//! Interactive presentation for the mesh.
class MeshPresentation : public MeshVS_Mesh
{
public:
//! Empty constructor.
Standard_EXPORT MeshPresentation();
//! Return presentation type.
virtual AIS_KindOfInteractive Type() const Standard_OVERRIDE { return AIS_KOI_Object; }
//! Return presentation signature.
virtual Standard_Integer Signature() const Standard_OVERRIDE { return 0; }
//! Setup new material.
virtual void SetMaterial (const Graphic3d_NameOfMaterial theName) Standard_OVERRIDE
{
SetMaterial (Graphic3d_MaterialAspect (theName));
}
//! Setup new material.
virtual void SetMaterial (const Graphic3d_MaterialAspect& theMat) Standard_OVERRIDE;
//! Override presentation compute.
virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode) Standard_OVERRIDE;
//! Setup closed flag.
void SetClosed (const bool theIsClosed);
public:
DEFINE_STANDARD_RTTIEXT(MeshPresentation, MeshVS_Mesh)
};
#endif // MeshPresentation_H

View File

@@ -0,0 +1,726 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifdef __APPLE__
#import <TargetConditionals.h>
#endif
#include "MeshPrsBuilder.h"
#include <Aspect_TypeOfLine.hxx>
#include <MeshVS_Buffer.hxx>
#include <MeshVS_DataSource.hxx>
#include <MeshVS_Drawer.hxx>
#include <MeshVS_DrawerAttribute.hxx>
#include <MeshVS_EntityType.hxx>
#include <MeshVS_Mesh.hxx>
#include <MeshVS_Tool.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_Texture2Dmanual.hxx>
#include <Image_PixMap.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HPackedMapOfInteger.hxx>
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
static const int THE_NB_COLORS = 128;
//! Auxiliary wrapper
class MeshTexture : public Graphic3d_Texture2Dmanual
{
public:
//! Main constructor.
MeshTexture (const TCollection_AsciiString& theFileName)
: Graphic3d_Texture2Dmanual (theFileName), myPathOrig (theFileName) {}
//! Image reader.
virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE
{
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(__ANDROID__)
// mobile version is build without FreeImage to reduce binaries size - use Qt instead
Handle(PixMapQt) anImage = new PixMapQt();
if(!anImage->Load (myPathOrig))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Can not read image ") + myPathOrig + "!", Message_Fail);
return Handle(Image_PixMap)();
}
return anImage;
#else
return Graphic3d_Texture2Dmanual::GetImage();
#endif
}
private:
TCollection_AsciiString myPathOrig;
public:
DEFINE_STANDARD_RTTIEXT(MeshTexture, Graphic3d_Texture2Dmanual)
};
DEFINE_STANDARD_HANDLE(MeshTexture, Graphic3d_Texture2Dmanual)
IMPLEMENT_STANDARD_RTTIEXT(MeshPrsTexture, Graphic3d_Texture2D)
IMPLEMENT_STANDARD_RTTIEXT(MeshTexture, Graphic3d_Texture2Dmanual)
IMPLEMENT_STANDARD_RTTIEXT(MeshPrsBuilder, MeshVS_PrsBuilder)
//================================================================
// Function : MeshPrsBuilder
// Purpose :
//================================================================
MeshPrsBuilder::MeshPrsBuilder (const Handle(MeshVS_Mesh)& theMesh,
const MeshVS_DisplayModeFlags& theFlags)
: MeshVS_PrsBuilder (theMesh, theFlags, Handle(MeshVS_DataSource)(), -1, MeshVS_BP_NodalColor),
myIsElemental (Standard_False),
myIsGrayscale (Standard_False),
myRangeFrom (0.0),
myRangeTo (1.0),
myToMapTexture(Standard_False),
myToFlipV (Standard_False)
{
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(__ANDROID__)
myToFlipV = Standard_True;
#else
myToFlipV = Standard_False;
#endif
SetExcluding (Standard_True);
}
//================================================================
// Function : buildTextured
// Purpose :
//================================================================
void MeshPrsBuilder::buildTextured (const Handle(Prs3d_Presentation)& thePrs,
const TColStd_PackedMapOfInteger& theIDs,
TColStd_PackedMapOfInteger& theIDsToExclude) const
{
myPrsGroup.Nullify();
Handle(MeshDataSource) aSource = Handle(MeshDataSource)::DownCast (GetDataSource());
Handle(MeshVS_Drawer) aDrawer = GetDrawer();
if (aSource.IsNull()
|| aDrawer.IsNull())
{
return;
}
// subtract the hidden elements and ids to exclude (to minimize allocated memory)
TColStd_PackedMapOfInteger anIDs;
anIDs.Assign (theIDs);
Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
if (!aHiddenElems.IsNull())
{
anIDs.Subtract (aHiddenElems->Map());
}
anIDs.Subtract (theIDsToExclude);
Standard_Boolean hasReflection = Standard_True;
Standard_Boolean isSmoothShading = Standard_False;
aDrawer->GetBoolean (MeshVS_DA_Reflection, hasReflection);
aDrawer->GetBoolean (MeshVS_DA_SmoothShading, isSmoothShading);
MeshGroup aFullGroup;
aFullGroup.NodeLower = aSource->Nodes().Lower();
aFullGroup.NodeUpper = aSource->Nodes().Upper();
aFullGroup.ElemLower = aSource->Elements().Lower();
aFullGroup.ElemUpper = aSource->Elements().Upper();
for (Standard_Integer aGroupIter = 0; aGroupIter == 0 || aGroupIter <= aSource->Groups().Upper(); ++aGroupIter)
{
const MeshGroup& aGroup = !aSource->Groups().IsEmpty() ? aSource->Groups().Value (aGroupIter) : aFullGroup;
const Standard_Integer aNbNodes = aGroup.NodeUpper - aGroup.NodeLower + 1;
if (aGroup.NodeLower < 0
|| aGroup.NodeUpper < 0
|| aGroup.ElemLower < 0
|| aGroup.ElemUpper < 0
|| aNbNodes < 1)
{
continue;
}
Handle(MeshTexture) aTexture;
if (!aGroup.Material.Texture.IsEmpty()
&& myToMapTexture
&& aSource->HasUV())
{
aTexture = new MeshTexture (aGroup.Material.Texture);
}
Standard_Integer aNbTris = 0;
for (Standard_Integer anElemIter = aGroup.ElemLower; anElemIter <= aGroup.ElemUpper; ++anElemIter)
{
if (!anIDs.Contains (anElemIter)) { continue; }
const Graphic3d_Vec4i& anElem = aSource->Elements().Value (anElemIter);
++aNbTris;
if (anElem[3] != -1)
{
++aNbTris;
}
}
if (aNbTris < 1)
{
continue;
}
Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3,
aSource->HasNormals() || isSmoothShading, Standard_False, !aTexture.IsNull());
// fill nodes
if (!aTexture.IsNull())
{
if (aSource->HasNormals())
{
for (Standard_Integer aNodeIter = aGroup.NodeLower; aNodeIter <= aGroup.NodeUpper; ++aNodeIter)
{
const Graphic3d_Vec3& aNode = aSource->Nodes() .Value (aNodeIter);
const Graphic3d_Vec3& aNorm = aSource->Normals().Value (aNodeIter);
const Graphic3d_Vec2& anUV = aSource->NodesUV().Value (aNodeIter);
const float aV = myToFlipV ? (1.0f - anUV.y()) : anUV.y();
aTriangles->AddVertex (aNode.x(), aNode.y(), aNode.z(),
aNorm.x(), aNorm.y(), aNorm.z(),
anUV.x(), aV);
}
}
else
{
for (Standard_Integer aNodeIter = aGroup.NodeLower; aNodeIter <= aGroup.NodeUpper; ++aNodeIter)
{
const Graphic3d_Vec3& aNode = aSource->Nodes() .Value (aNodeIter);
const Graphic3d_Vec2& anUV = aSource->NodesUV().Value (aNodeIter);
const float aV = myToFlipV ? (1.0f - anUV.y()) : anUV.y();
aTriangles->AddVertex (aNode.x(), aNode.y(), aNode.z(),
anUV.x(), aV);
}
}
}
else
{
if (aSource->HasNormals())
{
for (Standard_Integer aNodeIter = aGroup.NodeLower; aNodeIter <= aGroup.NodeUpper; ++aNodeIter)
{
const Graphic3d_Vec3& aNode = aSource->Nodes() .Value (aNodeIter);
const Graphic3d_Vec3& aNorm = aSource->Normals().Value (aNodeIter);
aTriangles->AddVertex (aNode.x(), aNode.y(), aNode.z(),
aNorm.x(), aNorm.y(), aNorm.z());
}
}
else
{
for (Standard_Integer aNodeIter = aGroup.NodeLower; aNodeIter <= aGroup.NodeUpper; ++aNodeIter)
{
const Graphic3d_Vec3& aNode = aSource->Nodes().Value (aNodeIter);
aTriangles->AddVertex (aNode.x(), aNode.y(), aNode.z());
}
}
}
// fill indices
for (Standard_Integer anElemIter = aGroup.ElemLower; anElemIter <= aGroup.ElemUpper; ++anElemIter)
{
if (!anIDs.Contains (anElemIter)) { continue; }
const Graphic3d_Vec4i& anElem = aSource->Elements().Value (anElemIter);
aTriangles->AddEdge (anElem[0] + 1 - aGroup.NodeLower);
aTriangles->AddEdge (anElem[1] + 1 - aGroup.NodeLower);
aTriangles->AddEdge (anElem[2] + 1 - aGroup.NodeLower);
if (anElem[3] != -1)
{
aTriangles->AddEdge (anElem[0] + 1 - aGroup.NodeLower);
aTriangles->AddEdge (anElem[2] + 1 - aGroup.NodeLower);
aTriangles->AddEdge (anElem[3] + 1 - aGroup.NodeLower);
}
}
// reconstruct normals
if (!aSource->HasNormals() && isSmoothShading)
{
// compute normal at each node, taking into account size of each element (e.g. without pre-normalization)
for (Standard_Integer anElemIter = aGroup.ElemLower; anElemIter <= aGroup.ElemUpper; ++anElemIter)
{
if (!anIDs.Contains (anElemIter)) { continue; }
const Graphic3d_Vec4i& anElem = aSource->Elements().Value (anElemIter);
const Graphic3d_Vec3& aNode0 = aSource->Nodes().Value (anElem[0]);
const Graphic3d_Vec3& aNode1 = aSource->Nodes().Value (anElem[1]);
const Graphic3d_Vec3& aNode2 = aSource->Nodes().Value (anElem[2]);
const Graphic3d_Vec3 aVec01 = aNode1 - aNode0;
const Graphic3d_Vec3 aVec02 = aNode2 - aNode0;
const Graphic3d_Vec3 aCross = Graphic3d_Vec3::Cross (aVec01, aVec02);
const Graphic3d_Vec3d aTriNorm (aCross.x(), aCross.y(), aCross.z());
const Standard_Integer aNbElemNodes = anElem[3] != -1 ? 4 : 3;
Graphic3d_Vec3d aNorm;
for (Standard_Integer aNodeIter = 0; aNodeIter < aNbElemNodes; ++aNodeIter)
{
// Graphic3d_ArrayOfPrimitives zeroes values in costructor
const Standard_Integer aNodeIndex = anElem[aNodeIter] + 1 - aGroup.NodeLower;
aTriangles->VertexNormal (aNodeIndex, aNorm.x(), aNorm.y(), aNorm.z());
aNorm += aTriNorm;
aTriangles->SetVertexNormal (aNodeIndex, aNorm.x(), aNorm.y(), aNorm.z());
}
}
// normalize
for (Standard_Integer anElemIter = aGroup.ElemLower; anElemIter <= aGroup.ElemUpper; ++anElemIter)
{
if (!anIDs.Contains (anElemIter)) { continue; }
const Graphic3d_Vec4i& anElem = aSource->Elements().Value (anElemIter);
const Standard_Integer aNbElemNodes = anElem[3] != -1 ? 4 : 3;
Graphic3d_Vec3d aNorm;
for (Standard_Integer aNodeIter = 0; aNodeIter < aNbElemNodes; ++aNodeIter)
{
const Standard_Integer aNodeIndex = anElem[aNodeIter] + 1 - aGroup.NodeLower;
aTriangles->VertexNormal (aNodeIndex, aNorm.x(), aNorm.y(), aNorm.z());
aNorm.Normalize();
aTriangles->SetVertexNormal (aNodeIndex, aNorm.x(), aNorm.y(), aNorm.z());
}
}
}
Graphic3d_MaterialAspect aMat[2];
aDrawer->GetMaterial(MeshVS_DA_FrontMaterial, aMat[0]);
aDrawer->GetMaterial(MeshVS_DA_BackMaterial, aMat[1]);
if (aMat[0].Name() == Graphic3d_NOM_DEFAULT
&& aGroup.Material.Aspect.Name() != Graphic3d_NOM_DEFAULT)
{
aMat[0] = aGroup.Material.Aspect;
aMat[1] = aGroup.Material.Aspect;
}
if (!hasReflection)
{
aMat[0].SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
aMat[0].SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
aMat[0].SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
aMat[0].SetReflectionModeOff (Graphic3d_TOR_EMISSION);
}
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = MeshVS_Tool::CreateAspectFillArea3d (aDrawer, aMat[0]);
if (!aTexture.IsNull())
{
anAreaAsp->SetTextureMap (aTexture);
anAreaAsp->SetTextureMapOn();
}
Handle(Graphic3d_Group) aPrsGroup = thePrs->NewGroup();
aPrsGroup->SetGroupPrimitivesAspect (anAreaAsp);
aPrsGroup->AddPrimitiveArray (aTriangles);
}
}
//================================================================
// Function : Build
// Purpose :
//================================================================
void MeshPrsBuilder::Build (const Handle(Prs3d_Presentation)& thePrs,
const TColStd_PackedMapOfInteger& theIDs,
TColStd_PackedMapOfInteger& theIDsToExclude,
const Standard_Boolean theIsElement,
const Standard_Integer theDisplayMode) const
{
myPrsGroup.Nullify();
if (myProperty.IsNull())
{
buildTextured (thePrs, theIDs, theIDsToExclude);
return;
}
Handle(MeshVS_DataSource) aSource = GetDataSource();
Handle(MeshVS_Drawer) aDrawer = GetDrawer();
if (aSource.IsNull()
|| aDrawer.IsNull()
|| myProperty.IsNull())
{
return;
}
Standard_Integer aMaxFaceNodes = 0;
if (!aDrawer->GetInteger (MeshVS_DA_MaxFaceNodes, aMaxFaceNodes)
|| aMaxFaceNodes <= 0 )
{
return;
}
MeshVS_Buffer aCoordsBuf (3 * aMaxFaceNodes * sizeof(Standard_Real));
TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * aMaxFaceNodes);
if ((theDisplayMode & GetFlags()) == 0
|| !theIsElement)
{
return;
}
const Standard_Real aLowerValue = propertyLowerValue();
const Standard_Real anUpperValue = propertyUpperValue();
const Standard_Real aRange = anUpperValue - aLowerValue;
// subtract the hidden elements and ids to exclude (to minimize allocated memory)
TColStd_PackedMapOfInteger anIDs;
anIDs.Assign (theIDs);
Handle(TColStd_HPackedMapOfInteger) aHiddenElems = myParentMesh->GetHiddenElems();
if (!aHiddenElems.IsNull())
{
anIDs.Subtract (aHiddenElems->Map());
}
anIDs.Subtract (theIDsToExclude);
Standard_Boolean isReflect = Standard_False, isMeshSmoothShading = Standard_False;
aDrawer->GetBoolean (MeshVS_DA_ColorReflection, isReflect);
aDrawer->GetBoolean (MeshVS_DA_SmoothShading, isMeshSmoothShading);
// Following parameter are used for texture presentation only
int nbColors = THE_NB_COLORS;///myTextureColorMap.Length(); // Number of colors from color map
int nbTextureColors = nbColors; // Number of colors in texture (it will be pow of 2)
Graphic3d_MaterialAspect aMaterials[2] =
{
Graphic3d_MaterialAspect (Graphic3d_NOM_PLASTIC),
Graphic3d_MaterialAspect (Graphic3d_NOM_PLASTIC)
};
for (Standard_Integer aMatIter = 0; aMatIter < 2; ++aMatIter)
{
Graphic3d_MaterialAspect& aMat = aMaterials[aMatIter];
if (!isReflect)
{
aMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
aMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
aMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
aMat.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
}
else
{
aMat.SetAmbient (0.5);
aMat.SetDiffuse (0.5);
aMat.SetSpecular(0.0);
aMat.SetEmissive(0.0);
}
}
Standard_Integer aNbFacePrimitives = 0;
Standard_Integer aNbEdgePrimitives = 0;
for (TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); it.More(); it.Next())
{
MeshVS_EntityType aType = MeshVS_ET_NONE;
Standard_Integer aNbNodes = 0;
if (!aSource->GetGeom (it.Key(), Standard_True, aCoords, aNbNodes, aType)
|| aType != MeshVS_ET_Face)
{
continue;
}
aNbEdgePrimitives += aNbNodes; // add edge segments
aNbFacePrimitives += aNbNodes - 2; // add face triangles
}
Standard_Boolean toShowEdges = Standard_True;
aDrawer->GetBoolean (MeshVS_DA_ShowEdges, toShowEdges);
// Here we do not use indices arrays because they are not effective for some mesh
// drawing modes: shrinking mode (displaces the vertices inside the polygon), 3D
// cell rendering (normal interpolation is not always applicable - flat shading),
// elemental coloring (color interpolation is impossible)
Handle(Graphic3d_ArrayOfTriangles) aFaceTriangles = new Graphic3d_ArrayOfTriangles (aNbFacePrimitives * 3, 0,
Standard_True, Standard_False, Standard_True);
Handle(Graphic3d_ArrayOfSegments) anEdgeSegments;
if (toShowEdges)
{
anEdgeSegments = new Graphic3d_ArrayOfSegments (aNbEdgePrimitives * 2);
}
gp_Pnt P, Start;
Standard_Real aMin = gp::Resolution() * gp::Resolution();
gp_Dir aDefNorm = gp::DZ();
TColStd_Array1OfInteger aNodes (1, 10);
for (TColStd_MapIteratorOfPackedMapOfInteger it (anIDs); it.More(); it.Next())
{
Standard_Integer aKey = it.Key();
Standard_Integer aNbNodes = 0;
MeshVS_EntityType aType = MeshVS_ET_NONE;
if (!aSource->GetGeom (aKey, Standard_True, aCoords, aNbNodes, aType)
|| aType != MeshVS_ET_Face
|| aNbNodes > 10
|| !aSource->GetNodesByElement (aKey, aNodes, aNbNodes))
{
continue;
}
// Preparing normal(s) to show reflections if requested
Handle(TColStd_HArray1OfReal) aNormals;
Standard_Boolean hasNormals = isReflect
&& aSource->GetNormalsByElement (aKey, isMeshSmoothShading, aMaxFaceNodes, aNormals);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbNodes - 2; ++aNodeIdx)
{
for (Standard_Integer aSubIdx = 0; aSubIdx < 3; ++aSubIdx)
{
gp_XYZ aPnt (aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aCoords (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
gp_Vec aNorm = aDefNorm;
if (hasNormals)
{
gp_Vec aTestNorm (aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 1),
aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 2),
aNormals->Value (3 * (aSubIdx == 0 ? 0 : (aNodeIdx + aSubIdx)) + 3));
if (aTestNorm.SquareMagnitude() > aMin)
{
aNorm = gp_Dir (aTestNorm);
}
}
// retrieve nodal value
Standard_Integer aNodeIndex = aKey;
if (!myIsElemental)
{
aNodeIndex = aNodes (aSubIdx == 0 ? 1 : (aNodeIdx + aSubIdx + 1));
}
Standard_Real aTexCoordU = 0.25;
Standard_Real aTexCoordV = 0.25;
const Standard_Real aValue = myProperty->Value (aNodeIndex);
if (aRange > gp::Resolution()
&& !IsNaN (aValue))
{
const Standard_Real aNormVal = (aValue - aLowerValue) / aRange;
aTexCoordU = (aNormVal * (nbColors - 1.0) + 0.5) / nbTextureColors;
aTexCoordV = 0.75;
}
// Transform texture coordinate in accordance with number of colors specified
// by upper level and real size of OpenGL texture. The OpenGL texture has border
// colors interpolated with the colors from the color map, thats why we need to
// shrink texture coordinates around the middle point to exclude areas where the
// map colors are interpolated with the borders color
aFaceTriangles->AddVertex (aPnt, aNorm, gp_Pnt2d (aTexCoordU, aTexCoordV));
}
}
if (!anEdgeSegments.IsNull())
{
for (Standard_Integer aNodeIdx = 0; aNodeIdx < aNbNodes; ++aNodeIdx) // border segmentation
{
const Standard_Integer aNextIdx = (aNodeIdx + 1) % aNbNodes;
anEdgeSegments->AddVertex (aCoords (3 * aNodeIdx + 1),
aCoords (3 * aNodeIdx + 2),
aCoords (3 * aNodeIdx + 3));
anEdgeSegments->AddVertex (aCoords (3 * aNextIdx + 1),
aCoords (3 * aNextIdx + 2),
aCoords (3 * aNextIdx + 3));
}
}
// if IsExcludingOn then presentation must not be built by other builders
if (IsExcludingOn())
{
theIDsToExclude.Add (aKey);
}
}
Aspect_TypeOfLine anEdgeType = Aspect_TOL_SOLID;
Standard_Integer anEdgeInt;
Standard_Real anEdgeWidth;
Quantity_Color anInteriorColor, anEdgeColor, aLineColor;
aDrawer->GetColor (MeshVS_DA_InteriorColor, anInteriorColor);
aDrawer->GetColor (MeshVS_DA_EdgeColor, anEdgeColor);
aDrawer->GetColor (MeshVS_DA_BeamColor, aLineColor);
aDrawer->GetDouble (MeshVS_DA_EdgeWidth, anEdgeWidth);
if (aDrawer->GetInteger (MeshVS_DA_EdgeType, anEdgeInt))
{
anEdgeType = (Aspect_TypeOfLine )anEdgeInt;
}
Handle(Prs3d_Drawer) aPrs3dDrawer = myParentMesh->Attributes();
if (aPrs3dDrawer.IsNull())
{
return;
}
aPrs3dDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
myFillAsp = new Graphic3d_AspectFillArea3d();
*myFillAsp = *aPrs3dDrawer->ShadingAspect()->Aspect();
myFillAsp->SetFrontMaterial(aMaterials[0]);
myFillAsp->SetBackMaterial (aMaterials[1]);
Handle(Graphic3d_Texture2D) aTexture = createTexture (myIsGrayscale, myRangeFrom, myRangeTo, myProperty->IsInversed());
if (aTexture.IsNull())
{
return;
}
myFillAsp->SetTextureMapOn();
myFillAsp->SetTextureMap (aTexture);
myFillAsp->SetInteriorColor (Quantity_NOC_WHITE);
myFillAsp->SetDistinguishOff();
myFillAsp->SetEdgeOff();
Handle(Graphic3d_Group) aGroup1 = thePrs->NewGroup();
aGroup1->SetGroupPrimitivesAspect (myFillAsp);
aGroup1->AddPrimitiveArray (aFaceTriangles);
myPrsGroup = aGroup1;
if (toShowEdges)
{
Handle(Graphic3d_Group) aGroup2 = thePrs->NewGroup();
Handle(Graphic3d_AspectLine3d) anLAsp = new Graphic3d_AspectLine3d (anEdgeColor, anEdgeType, anEdgeWidth);
aGroup2->SetGroupPrimitivesAspect (anLAsp);
aGroup2->AddPrimitiveArray (anEdgeSegments);
}
}
//================================================================
// Function : SetProperty
// Purpose :
//================================================================
void MeshPrsBuilder::SetProperty (const Handle(MeshScalarProperty)& theProperty,
const Standard_Boolean theIsElemental)
{
myProperty = theProperty;
myIsElemental = theIsElemental;
if (!myProperty.IsNull())
{
myRangeFrom = myProperty->ColorscaleRangeFrom();
myRangeTo = myProperty->ColorscaleRangeTo();
}
}
//================================================================
// Function : SetRange
// Purpose :
//================================================================
void MeshPrsBuilder::SetRange (const Standard_Real theFrom,
const Standard_Real theTo,
const bool theIsInversed)
{
Standard_Real aPrec = 1.0 / Standard_Real(THE_NB_COLORS * 10);
if (Abs (myRangeFrom - theFrom) < aPrec
&& Abs (myRangeTo - theTo) < aPrec
&& (myProperty.IsNull() || myProperty->IsInversed() == theIsInversed))
{
return;
}
myRangeFrom = theFrom;
myRangeTo = theTo;
if (!myProperty.IsNull())
{
myProperty->SetInversed (theIsInversed);
myProperty->SetColorscaleRange (theFrom, theTo);
}
if (myPrsGroup.IsNull())
{
return;
}
Handle(Graphic3d_Texture2D) aTexture = createTexture (myIsGrayscale, myRangeFrom, myRangeTo, theIsInversed);
if (aTexture.IsNull())
{
return;
}
myFillAsp->SetTextureMap (aTexture);
myPrsGroup->SetGroupPrimitivesAspect (myFillAsp);
}
//================================================================
// Function : createTexture
// Purpose :
//================================================================
Handle(Graphic3d_Texture2D) MeshPrsBuilder::createTexture (const Standard_Boolean theIsGrayscale,
const Standard_Real theFrom,
const Standard_Real theTo,
const bool theIsInversed)
{
const Standard_Integer aNbColors = THE_NB_COLORS;
const Graphic3d_Vec3d anOut = Graphic3d_Vec3d (0.5, 0.5, 0.5);
Graphic3d_Vec3d aScale00 = theIsGrayscale ? Graphic3d_Vec3d (0.0, 0.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
Graphic3d_Vec3d aScale05 = theIsGrayscale ? Graphic3d_Vec3d (0.5, 0.5, 0.5) : Graphic3d_Vec3d (0.0, 1.0, 0.0);
Graphic3d_Vec3d aScale10 = theIsGrayscale ? Graphic3d_Vec3d (1.0, 1.0, 1.0) : Graphic3d_Vec3d (1.0, 0.0, 0.0);
if (theIsInversed)
{
std::swap (aScale00, aScale10);
}
const Standard_Real aRange = Max (theTo - theFrom, 0.01);
const Standard_Real aRangeInv = 1.0 / aRange;
const Standard_Real aMiddle = theFrom + 0.5 * aRange;
const Standard_Real aFrom = theFrom;
// create and fill image with colors
Handle(Image_PixMap) anImage = new Image_PixMap();
if (!anImage->InitTrash (Image_PixMap::ImgRGBA, aNbColors, 2))
{
return NULL;
}
Image_ColorRGBA anOutColor;
anOutColor.r() = Standard_Byte(255.0 * anOut.r());
anOutColor.g() = Standard_Byte(255.0 * anOut.g());
anOutColor.b() = Standard_Byte(255.0 * anOut.b());
anOutColor.a() = 0xFF;
anImage->SetTopDown (false);
for (Standard_Size aColIter = 0; aColIter < Standard_Size(aNbColors); ++aColIter)
{
const Standard_Real aValue = Standard_Real(aColIter) / Standard_Real(aNbColors - 1);
Graphic3d_Vec3d aColorVal;
if (aValue < theFrom
|| aValue > theTo)
{
aColorVal = anOut;
}
else if (aValue < aMiddle)
{
const Standard_Real aHalfVal = (aValue - aFrom) * 2.0 * aRangeInv;
aColorVal = aScale00 * (1.0 - aHalfVal) + aScale05 * aHalfVal;
}
else
{
const Standard_Real aHalfVal = (aValue - aFrom) * 2.0 * aRangeInv - 1.0;
aColorVal = aScale05 * (1.0 - aHalfVal) + aScale10 * aHalfVal;
}
Image_ColorRGBA& aColor0 = anImage->ChangeValue<Image_ColorRGBA> (0, aColIter);
Image_ColorRGBA& aColor1 = anImage->ChangeValue<Image_ColorRGBA> (1, aColIter);
aColor0.r() = Standard_Byte(255.0 * aColorVal.r());
aColor0.g() = Standard_Byte(255.0 * aColorVal.g());
aColor0.b() = Standard_Byte(255.0 * aColorVal.b());
aColor0.a() = 0xFF;
aColor1 = anOutColor;
}
// create texture
return new MeshPrsTexture (anImage);
}

147
src/MeshVS/MeshPrsBuilder.h Normal file
View File

@@ -0,0 +1,147 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef MeshPrsBuilder_H
#define MeshPrsBuilder_H
#include "MeshDataSource.h"
#include <MeshVS_PrsBuilder.hxx>
#include <Graphic3d_Texture2D.hxx>
#include <Graphic3d_TextureParams.hxx>
//! Auxiliary class to hold texture.
class MeshPrsTexture : public Graphic3d_Texture2D
{
public:
MeshPrsTexture (const Handle(Image_PixMap)& theImg)
: Graphic3d_Texture2D (theImg, Graphic3d_TOT_2D)
{
myParams->SetModulate (Standard_True);
myParams->SetFilter (Graphic3d_TOTF_BILINEAR);
}
public:
DEFINE_STANDARD_RTTIEXT(MeshPrsTexture, Graphic3d_Texture2D)
};
DEFINE_STANDARD_HANDLE(MeshPrsTexture, Graphic3d_Texture2D)
//! Auxiliary builder for Nodal or Elemental mesh properties using textured colorscale.
class MeshPrsBuilder : public MeshVS_PrsBuilder
{
public:
//! Default constructor.
Standard_EXPORT MeshPrsBuilder (const Handle(MeshVS_Mesh)& theMesh,
const MeshVS_DisplayModeFlags& theFlags);
//! Setup textures when available.
Standard_Boolean ToMapTextures() const { return myToMapTexture; }
//! Setup textures when available.
void SetMapTextures (const Standard_Boolean theToMap) { myToMapTexture = theToMap; }
public:
//! Setup property to display.
Standard_EXPORT void SetProperty (const Handle(MeshScalarProperty)& theProperty,
const Standard_Boolean theIsElemental);
//! Grayscale flag.
Standard_Boolean IsGrayscale() const
{
return myIsGrayscale;
}
//! Specify using grayscale or B->G->R colorscale
void SetGrayscale (const Standard_Boolean theIsGrayscale)
{
myIsGrayscale = theIsGrayscale;
}
//! Adjust colorscale range.
Standard_EXPORT void SetRange (const Standard_Real theFrom,
const Standard_Real theTo,
const bool theIsInversed);
public:
//! Main builder.
Standard_EXPORT virtual void Build (const Handle(Prs3d_Presentation)& thePrs,
const TColStd_PackedMapOfInteger& theIDs,
TColStd_PackedMapOfInteger& theIDsToExclude,
const Standard_Boolean theIsElement,
const Standard_Integer theDisplayMode) const Standard_OVERRIDE;
protected:
//! Textured presentation builder.
void buildTextured (const Handle(Prs3d_Presentation)& thePrs,
const TColStd_PackedMapOfInteger& theIDs,
TColStd_PackedMapOfInteger& theIDsToExclude) const;
//! Auxiliary method to create texture.
static Handle(Graphic3d_Texture2D) createTexture (const Standard_Boolean theIsGrayscale,
const Standard_Real theFrom,
const Standard_Real theTo,
const bool theIsInversed);
//! Return lower property value.
Standard_Real propertyLowerValue() const
{
if (myProperty.IsNull())
{
return 0.0;
}
return myIsGrayscale ? Min (0.0, myProperty->LowerValue()) : myProperty->LowerValue();
}
//! Return upper property value.
Standard_Real propertyUpperValue() const
{
if (myProperty.IsNull())
{
return 1.0;
}
return myIsGrayscale ? Max (1.0, myProperty->UpperValue()) : myProperty->UpperValue();
}
protected:
Handle(MeshScalarProperty) myProperty; //!< property to display
Standard_Boolean myIsElemental; //!< flag indicating elemental property
Standard_Boolean myIsGrayscale; //!< flag to create grayscale colorscale
Standard_Real myRangeFrom; //!< colorscale range, lower value
Standard_Real myRangeTo; //!< colorscale range, upper value
Standard_Boolean myToMapTexture;//!< setup textures when available
Standard_Boolean myToFlipV; //!< flip texture coordinates vertically
mutable Handle(Graphic3d_Group) myPrsGroup; //!< presentation group with triangles
mutable Handle(Graphic3d_AspectFillArea3d) myFillAsp;
public:
DEFINE_STANDARD_RTTIEXT(MeshPrsBuilder, MeshVS_PrsBuilder)
};
DEFINE_STANDARD_HANDLE(MeshPrsBuilder, MeshVS_PrsBuilder)
#endif // MeshPrsBuilder_H

View File

@@ -0,0 +1,124 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef MeshScalarProperty_H
#define MeshScalarProperty_H
#include <gp_XYZ.hxx>
#include <Graphic3d_Vec.hxx>
#include <NCollection_Vector.hxx>
#include <NCollection_Sequence.hxx>
#include <Precision.hxx>
#include <TCollection_AsciiString.hxx>
//! Return true for NaN.
inline bool IsNaN (const double theValue)
{
#if defined(_MSC_VER)
return ::_isnan (theValue) != 0;
#else
return std::isnan (theValue);
#endif
}
//! Property assigned to Mesh elements or nodes
class MeshScalarProperty : public Standard_Transient
{
public:
//! Return property name.
const TCollection_AsciiString& Name() const { return myName; }
//! Return lower index.
Standard_Integer LowerIndex() const { return myValues.Lower(); }
//! Return upper index.
Standard_Integer UpperIndex() const { return myValues.Upper(); }
//! Return value for specified index.
Standard_Real Value (const Standard_Integer theIndex) const { return myValues.Value (theIndex); }
//! Return lower value of the property.
Standard_Real LowerValue() const { return myValueLower; }
//! Return lower value of the property.
Standard_Real UpperValue() const { return myValueUpper; }
//! Return true if values has opposite meaning (greater value is better).
bool IsInversed() const { return myIsInversed; }
//! Setup flag inficating that values has opposite meaning (greater value is better) or normal meaning (greater value is badder).
void SetInversed(const bool theIsInversed) { myIsInversed = theIsInversed; }
//! Return colorscale range (from).
Standard_Real ColorscaleRangeFrom() const { return myCSRangeFrom; }
//! Return colorscale range (to).
Standard_Real ColorscaleRangeTo() const { return myCSRangeTo; }
//! Setup colorscale range.
void SetColorscaleRange (const Standard_Real theFrom,
const Standard_Real theTo)
{
myCSRangeFrom = theFrom;
myCSRangeTo = theTo;
}
public:
//! Default constructor.
MeshScalarProperty (const TCollection_AsciiString& theName)
: myName (theName),
myValueLower ( Precision::Infinite()),
myValueUpper (-Precision::Infinite()),
myCSRangeFrom(0.0),
myCSRangeTo (1.0),
myIsInversed (false)
{}
//! Append new value
void AppendValue (const Standard_Real theValue)
{
myValues.Append ((float )theValue);
if (!IsNaN (theValue))
{
myValueLower = Min (myValueLower, theValue);
myValueUpper = Max (myValueUpper, theValue);
}
}
protected:
TCollection_AsciiString myName; //!< property name
//NCollection_Vector<Standard_Real> myValues; //!< property values
NCollection_Vector<float> myValues; //!< property values
Standard_Real myValueLower; //!< values range - lower value
Standard_Real myValueUpper; //!< values range - upper value
Standard_Real myCSRangeFrom;//!< colorscale range - from
Standard_Real myCSRangeTo; //!< colorscale range - to
bool myIsInversed; //!< values meaning
public:
DEFINE_STANDARD_RTTIEXT(MeshScalarProperty, Standard_Transient)
};
DEFINE_STANDARD_HANDLE(MeshScalarProperty, Standard_Transient)
typedef NCollection_Vector<Handle(MeshScalarProperty)> MeshScalarProperties;
#endif // MeshScalarProperty_H

View File

@@ -0,0 +1,680 @@
// 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 <ObjDataSource.h>
#include <Standard_CLocaleSentry.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressSentry.hxx>
#include <OSD_OpenFile.hxx>
#include <OSD_Timer.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Quantity_Color.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ObjDataSource, MeshDataSource)
//! Simple wrapper.
struct FileSentry
{
FILE* File;
FileSentry (const TCollection_AsciiString& theFile)
: File (OSD_OpenFile (theFile.ToCString(), "rb")) {}
~FileSentry()
{
if (File != NULL)
{
::fclose (File);
}
}
};
//! Read 3 float values.
inline bool objReadVec3 (const char* thePos,
char*& theNext,
Graphic3d_Vec3& theVec)
{
const char* aPos = thePos;
theVec.x() = (float )Strtod (aPos, &theNext);
aPos = theNext;
theVec.y() = (float )Strtod (aPos, &theNext);
aPos = theNext;
theVec.z() = (float )Strtod (aPos, &theNext);
return aPos != theNext;
}
//! Read string.
inline bool objReadName (const char* thePos,
TCollection_AsciiString& theName)
{
TCollection_AsciiString aName = TCollection_AsciiString (thePos);
Standard_Integer aTail = aName.Length();
if (aTail > 0
&& aName.Value (aTail) == '\n')
{
aName.SetValue (aTail--, '\0'); // replace '\n'
}
if (aTail > 0
&& aName.Value (aTail) == '\r')
{
aName.SetValue (aTail--, '\0'); // replace '\r'
}
theName = aName.ToCString();
theName.LeftAdjust();
theName.RightAdjust();
return !theName.IsEmpty();
}
//! Reader of mtl files.
class ObjMaterialReader
{
public:
//! Main constructor.
ObjMaterialReader (NCollection_DataMap<TCollection_AsciiString, MeshMaterial>& theMaterials)
: myFile (NULL), myMaterials (&theMaterials), myNbLines (0) {}
//! Destructor.
~ObjMaterialReader()
{
if (myFile != NULL)
{
::fclose (myFile);
}
}
//! Read the file.
Standard_Boolean Read (const TCollection_AsciiString& theFolder,
const TCollection_AsciiString& theFile)
{
myPath = theFolder + theFile;
myFile = OSD_OpenFile (myPath.ToCString(), "rb");
if (myFile == NULL)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("OBJ material file '") + myPath + "' is not found!", Message_Warning);
return Standard_False;
}
char aLine[256] = {};
TCollection_AsciiString aMatName;
MeshMaterial aMat;
const Standard_Integer aNbMatOld = myMaterials->Extent();
bool hasAspect = false;
for (; ::feof (myFile) == 0 && ::fgets (aLine, 255, myFile) != NULL; )
{
++myNbLines;
const char* aPos = aLine;
if (*aLine == '#'
|| *aLine == '\n'
|| *aLine == '\0')
{
continue;
}
if (::memcmp (aLine, "newmtl ", 7) == 0)
{
aPos += 7;
if (!aMatName.IsEmpty())
{
if (hasAspect)
{
aMat.Aspect.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
aMat.Aspect.SetMaterialName (aMatName.ToCString());
}
else
{
// reset incomplete material definition
aMat.Aspect = Graphic3d_MaterialAspect();
}
myMaterials->Bind (aMatName, aMat);
hasAspect = false;
}
aMatName = TCollection_AsciiString(aPos);
aMat = MeshMaterial();
if (!objReadName (aPos, aMatName))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Empty OBJ material at line ") + myNbLines + " in file " + myPath, Message_Warning);
}
}
else if (::memcmp (aLine, "Ka ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Graphic3d_Vec3 aColor;
objReadVec3 (aPos, aNext, aColor);
aPos = aNext;
if (validateColor (aColor))
{
Quantity_Color aQColor (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
aMat.Aspect.SetAmbientColor (aQColor);
hasAspect = true;
}
}
else if (::memcmp (aLine, "Kd ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Graphic3d_Vec3 aColor;
objReadVec3 (aPos, aNext, aColor);
aPos = aNext;
if (validateColor (aColor))
{
Quantity_Color aQColor (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
aMat.Aspect.SetDiffuseColor (aQColor);
hasAspect = true;
}
}
else if (::memcmp (aLine, "Ks ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Graphic3d_Vec3 aColor;
objReadVec3 (aPos, aNext, aColor);
aPos = aNext;
if (validateColor (aColor))
{
Quantity_Color aQColor (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
aMat.Aspect.SetSpecularColor (aQColor);
}
}
else if (::memcmp (aLine, "Ns ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Standard_Real aSpecular = Strtod (aPos, &aNext);
aPos = aNext;
if (aSpecular >= 0.0
&& aSpecular <= 128.0)
{
aMat.Aspect.SetShininess (aSpecular / 128.0);
}
}
else if (::memcmp (aLine, "Tr ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Standard_Real anAlpha = Strtod (aPos, &aNext);
aPos = aNext;
if (validateScalar (anAlpha))
{
//aMat.Aspect.SetTransparency (anAlpha);
}
}
else if (::memcmp (aLine, "map_Kd ", 7) == 0)
{
aPos += 7;
if (!objReadName (aPos, aMat.Texture))
{
//
}
else
{
aMat.Texture = theFolder + aMat.Texture;
}
}
/*else if (::memcmp (aLine, "illum ", 6) == 0)
{
aPos += 6;
char* aNext = NULL;
const int aModel = strtol (aPos, &aNext, 10);
aPos = aNext;
if (aModel < 0 || aModel > 10)
{
// unknown model
}
}*/
}
if (!aMatName.IsEmpty())
{
if (hasAspect)
{
aMat.Aspect.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
aMat.Aspect.SetMaterialName (aMatName.ToCString());
}
else
{
// reset incomplete material definition
aMat.Aspect = Graphic3d_MaterialAspect();
}
myMaterials->Bind (aMatName, aMat);
}
return myMaterials->Extent() != aNbMatOld;
}
private:
//! Validate scalar value
inline bool validateScalar (const Standard_Real theValue)
{
if (theValue < 0.0
|| theValue > 1.0)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid scalar in OBJ material at line ") + myNbLines + " in file " + myPath, Message_Warning);
return false;
}
return true;
}
//! Validate RGB color
inline bool validateColor (const Graphic3d_Vec3& theVec)
{
if (theVec.r() < 0.0 || theVec.r() > 1.0
|| theVec.g() < 0.0 || theVec.g() > 1.0
|| theVec.b() < 0.0 || theVec.b() > 1.0)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid color in OBJ material at line ") + myNbLines + " in file " + myPath, Message_Warning);
return false;
}
return true;
}
private:
FILE* myFile;
TCollection_AsciiString myPath;
NCollection_DataMap<TCollection_AsciiString, MeshMaterial>* myMaterials;
Standard_Integer myNbLines;
};
//================================================================
// Function : Constructor
// Purpose :
//================================================================
ObjDataSource::ObjDataSource()
{
//
}
//! Hasher for 3 ordered integers.
class ObjVec3iHasher
{
public:
static Standard_Integer HashCode (const Graphic3d_Vec3i& theKey,
const Standard_Integer theUpper)
{
return ::HashCode (::HashCodes ((Standard_CString )&theKey, sizeof(Graphic3d_Vec3i)), theUpper);
}
static Standard_Boolean IsEqual (const Graphic3d_Vec3i& theKey1,
const Graphic3d_Vec3i& theKey2)
{
return theKey1[0] == theKey2[0]
&& theKey1[1] == theKey2[1]
&& theKey1[2] == theKey2[2];
}
};
//================================================================
// Function : Read
// Purpose :
//================================================================
Standard_Boolean ObjDataSource::Read (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Integer /*theIndexLimit*/,
const Standard_Integer theMemLimitMiB)
{
Clear();
Standard_CLocaleSentry aLocaleSentry;
FileSentry aFile (theFile);
if (aFile.File == NULL)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("File '") + theFile + "' is not found!", Message_Fail);
return Standard_False;
}
// determine file location to load associated files
TCollection_AsciiString aFolder;
{
OSD_Path aPath (theFile);
aPath.SetName ("");
aPath.SetExtension ("");
aPath.SystemName (aFolder);
}
// determine length of file
::fseek64 (aFile.File, 0, SEEK_END);
const int64_t aFileLen = ::ftell64 (aFile.File);
if (aFileLen <= 0L)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("File '") + theFile + "' is empty!", Message_Fail);
return Standard_False;
}
::fseek64 (aFile.File, 0, SEEK_SET);
const Standard_Integer aNbMiBTotal = Standard_Integer(aFileLen / (1024 * 1024));
Standard_Integer aNbMiBPassed = 0;
Message_ProgressSentry aPSentry (theProgress, "Reading text OBJ file", 0, aNbMiBTotal, 1);
OSD_Timer aTimer;
aTimer.Start();
// Each node in the Element specifies independent indices of Vertex position, Texture coordinates and Normal.
// This scheme does not match natural definition of Primitive Array where each unique set of nodal properties defines Vertex
// (thus node at the same location but with different normal should be duplicated).
// The following code converts OBJ definition of nodal properties to Primitive Array definition.
NCollection_Vector<Graphic3d_Vec3> aVerts;
NCollection_Vector<Graphic3d_Vec2> aVertParams;
NCollection_Vector<Graphic3d_Vec3> aNorms;
NCollection_DataMap<Graphic3d_Vec3i, Standard_Integer, ObjVec3iHasher> aPackedIndices;
NCollection_DataMap<TCollection_AsciiString, MeshMaterial> aMaterials;
TCollection_AsciiString anActiveMat;
MeshGroup aGroup;
const size_t aMemLimitBytes = theMemLimitMiB == -1
? size_t(-1)
: (theMemLimitMiB * 1024 * 1024);
size_t aMemEstim = 0;
char aLine[256] = {};
Standard_Integer aNbLines = 0;
bool isStart = true;
for (; ::feof (aFile.File) == 0 && ::fgets (aLine, 255, aFile.File) != NULL; )
{
++aNbLines;
if (aTimer.ElapsedTime() > 1.0)
{
if (!aPSentry.More())
{
return Standard_False;
}
const Standard_Integer aNbMiBRead = Standard_Integer(::ftell64 (aFile.File) / (1024 * 1024));
for (; aNbMiBPassed < aNbMiBRead; ++aNbMiBPassed) { aPSentry.Next(); }
aTimer.Reset();
aTimer.Start();
}
const char* aPos = aLine;
if (*aLine == '#')
{
if (isStart)
{
TCollection_AsciiString aComment (aLine + 1);
aComment.LeftAdjust();
aComment.RightAdjust();
if (!aComment.IsEmpty())
{
myComments.Append (aComment);
}
}
continue;
}
else if (*aLine == '\n'
|| *aLine == '\0')
{
continue;
}
isStart = false;
if (::memcmp (aLine, "v ", 2) == 0)
{
aPos += 2;
char* aNext = NULL;
Graphic3d_Vec3 aVert;
objReadVec3 (aPos, aNext, aVert);
aPos = aNext;
aMemEstim += sizeof(Graphic3d_Vec3);
if (aMemEstim >= aMemLimitBytes)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("OBJ file contains more than ") + myElements.Size() + " elements and " + aVerts.Size() + " vertices"
+ "\nwhich does not fit into " + theMemLimitMiB + " MiB limit."
+ "\nMesh data will be truncated!", Message_Fail);
return Standard_False;
}
aVerts.Append (aVert);
}
else if (::memcmp (aLine, "vn ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Graphic3d_Vec3 aNorm;
objReadVec3 (aPos, aNext, aNorm);
aPos = aNext;
aMemEstim += sizeof(Graphic3d_Vec3);
if (aMemEstim >= aMemLimitBytes)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("OBJ file contains more than ") + myElements.Size() + " elements and " + aVerts.Size() + " vertices"
+ "\nwhich does not fit into " + theMemLimitMiB + " MiB limit."
+ "\nMesh data will be truncated!", Message_Fail);
return Standard_False;
}
aNorms.Append (aNorm);
}
else if (::memcmp (aLine, "vt ", 3) == 0)
{
aPos += 3;
char* aNext = NULL;
Graphic3d_Vec2 anUV;
anUV.x() = (float )Strtod (aPos, &aNext);
aPos = aNext;
anUV.y() = (float )Strtod (aPos, &aNext);
aPos = aNext;
aMemEstim += sizeof(Graphic3d_Vec2);
if (aMemEstim >= aMemLimitBytes)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("OBJ file contains more than ") + myElements.Size() + " elements and " + aVerts.Size() + " vertices"
+ "\nwhich does not fit into " + theMemLimitMiB + " MiB limit."
+ "\nMesh data will be truncated!", Message_Fail);
return Standard_False;
}
aVertParams.Append (anUV);
}
else if (::memcmp (aLine, "f ", 2) == 0)
{
aPos += 2;
char* aNext = NULL;
Graphic3d_Vec4i aTriNodes (-1, -1, -1, -1);
for (int aNode = 0; aNode < 4; ++aNode)
{
Graphic3d_Vec3i a3Indices (-1, -1, -1);
a3Indices[0] = strtol (aPos, &aNext, 10) - 1;
if (aNext == aPos)
{
continue;
}
// parse UV index
aPos = aNext;
if (*aPos == '/')
{
++aPos;
a3Indices[1] = strtol (aPos, &aNext, 10) - 1;
aPos = aNext;
// parse Normal index
if (*aPos == '/')
{
++aPos;
a3Indices[2] = strtol (aPos, &aNext, 10) - 1;
aPos = aNext;
}
}
if (*aPos != ' '
&& *aPos != '\n'
&& *aPos != '\0')
{
++aPos;
}
// handle negative indices
if (a3Indices[0] < -1)
{
a3Indices[0] += aVerts.Upper() + 2;
}
if (a3Indices[1] < -1)
{
a3Indices[1] += aVertParams.Upper() + 2;
}
if (a3Indices[2] < -1)
{
a3Indices[2] += aNorms.Upper() + 2;
}
Standard_Integer anIndex = -1;
if (!aPackedIndices.Find (a3Indices, anIndex))
{
if (a3Indices[0] >= 0)
{
aMemEstim += sizeof(Graphic3d_Vec3);
}
if (a3Indices[1] >= 0)
{
aMemEstim += sizeof(Graphic3d_Vec2);
}
if (a3Indices[2] >= 0)
{
aMemEstim += sizeof(Graphic3d_Vec3);
}
aMemEstim += sizeof(Graphic3d_Vec4i) + sizeof(Standard_Integer); // naive map
if (aMemEstim >= aMemLimitBytes)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("OBJ file contains more than ") + myElements.Size() + " elements and " + aVerts.Size() + " vertices"
+ "\nwhich does not fit into " + theMemLimitMiB + " MiB limit."
+ "\nMesh data will be truncated!", Message_Fail);
return Standard_False;
}
if (a3Indices[0] < aVerts.Lower() || a3Indices[0] > aVerts.Upper())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Fail);
return Standard_False;
}
AddNodePosition (aVerts.Value (a3Indices[0]));
aGroup.NodeUpper = myNodes.Upper();
if (aGroup.NodeLower < 0)
{
aGroup.NodeLower = aGroup.NodeUpper;
}
if (a3Indices[1] >= 0)
{
if (a3Indices[1] < aVertParams.Lower() || a3Indices[1] > aVertParams.Upper())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Fail);
return Standard_False;
}
AddNodeUV (aVertParams.Value (a3Indices[1]));
}
if (a3Indices[2] >= 0)
{
if (a3Indices[2] < aNorms.Lower() || a3Indices[2] > aNorms.Upper())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Fail);
return Standard_False;
}
AddNodeNormal (aNorms.Value (a3Indices[2]));
}
anIndex = myNodes.Upper();
aPackedIndices.Bind (a3Indices, anIndex);
}
aTriNodes[aNode] = anIndex;
}
if (aTriNodes[0] < 0
|| aTriNodes[1] < 0
|| aTriNodes[2] < 0)
{
continue;
}
aMemEstim += sizeof(Graphic3d_Vec4i);
if (aMemEstim >= aMemLimitBytes)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("OBJ file contains more than ") + myElements.Size() + " elements and " + aVerts.Size() + " vertices"
+ "\nwhich does not fit into " + theMemLimitMiB + " MiB limit."
+ "\nMesh data will be truncated!", Message_Fail);
return Standard_False;
}
AddElement (aTriNodes);
aGroup.ElemUpper = myElements.Upper();
if (aGroup.ElemLower < 0)
{
aGroup.ElemLower = aGroup.ElemUpper;
if (!anActiveMat.IsEmpty())
{
aMaterials.Find (anActiveMat, aGroup.Material);
}
}
}
else if (::memcmp (aLine, "g ", 2) == 0)
{
if (aGroup.ElemLower >= 0
&& aGroup.ElemLower != aGroup.ElemUpper)
{
myGroups.Append (aGroup);
aGroup = MeshGroup();
aPackedIndices.Clear(); // vertices might be duplicated after this...
}
TCollection_AsciiString aGroupName;
if (!objReadName (aPos + 2, aGroupName))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Warning);
continue;
}
}
else if (::memcmp (aLine, "mtllib ", 7) == 0)
{
TCollection_AsciiString aMatPath;
if (!objReadName (aPos + 7, aMatPath))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Warning);
continue;
}
ObjMaterialReader aMatReader (aMaterials);
aMatReader.Read (aFolder, aMatPath);
}
else if (::memcmp (aLine, "usemtl ", 7) == 0)
{
TCollection_AsciiString aMatName;
if (!objReadName (aPos + 7, aMatName))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Invalid OBJ syntax at line ") + aNbLines, Message_Warning);
continue;
}
else if (!aMaterials.IsBound (aMatName))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Use of undefined OBJ material at line ") + aNbLines, Message_Warning);
continue;
}
anActiveMat = aMatName;
}
}
if (aGroup.ElemLower >= 0
&& aGroup.ElemLower != aGroup.ElemUpper)
{
myGroups.Append (aGroup);
}
for (; aNbMiBPassed < aNbMiBTotal; ++aNbMiBPassed) { aPSentry.Next(); }
return Standard_True;
}

View File

@@ -0,0 +1,43 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef ObjDataSource_H
#define ObjDataSource_H
#include <MeshDataSource.h>
//! The DataSource for working with OBJ mesh reader.
class ObjDataSource : public MeshDataSource
{
public:
//! Empty constructor.
Standard_EXPORT ObjDataSource();
//! Read the mesh from specified file.
Standard_EXPORT virtual Standard_Boolean Read (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Integer theIndexLimit,
const Standard_Integer theMemoryLimitMiB) Standard_OVERRIDE;
public:
DEFINE_STANDARD_RTTIEXT(ObjDataSource, MeshDataSource)
};
DEFINE_STANDARD_HANDLE(ObjDataSource, MeshDataSource)
#endif // ObjDataSource_H

View File

@@ -0,0 +1,354 @@
// 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 <ObjDataWriter.h>
#include <FaceIterator.h>
#include <CafShapePrs.h>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepLProp_SLProps.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressSentry.hxx>
#include <OSD_OpenFile.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_Triangulation.hxx>
#include <Standard_CLocaleSentry.hxx>
#include <TDataStd_Name.hxx>
#include <TopoDS.hxx>
IMPLEMENT_STANDARD_RTTIEXT(ObjDataWriter, Standard_Transient)
//! Auxiliary class to write OBJ.
class ObjWriter
{
public:
//! Main constructor.
ObjWriter (const TCollection_AsciiString& theName,
const Standard_Boolean theHasNormals)
: myFile (OSD_OpenFile (theName.ToCString(), "wb")),
myName (theName),
myHasNormals (theHasNormals == Standard_True)
{
if (myFile == NULL)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("File can not be created!\n") + theName, Message_Fail);
return;
}
}
//! Destructor, will emit error message if file was not closed.
~ObjWriter()
{
if (myFile != NULL)
{
::fclose (myFile);
Message::DefaultMessenger()->Send (TCollection_AsciiString ("File can not be written!\n") + myName, Message_Fail);
}
}
//! Return true if file has been opened.
bool IsOpened() const { return myFile != NULL; }
//! Correctly close the file.
void Close()
{
::fclose (myFile);
myFile = NULL;
}
//! Write the header.
bool WriteHeader (const Standard_Integer theNbNodes,
const Standard_Integer theNbElems)
{
return ::Fprintf (myFile, "# Exported by OpenCASCADE CAD Assistant [www.opencascade.com]\n"
"# Vertices: %d\n"
"# Faces: %d\n", theNbNodes, theNbElems) != 0;
}
//! Writing a triangle
bool WriteTriangle (const Graphic3d_Vec4i& theTri)
{
if (myHasNormals)
{
return Fprintf (myFile, "f %d//%d %d//%d %d//%d\n",
theTri[0] + 1, theTri[0] + 1,
theTri[1] + 1, theTri[1] + 1,
theTri[2] + 1, theTri[2] + 1) != 0;
}
return Fprintf (myFile, "f %d %d %d\n",
theTri[0] + 1,
theTri[1] + 1,
theTri[2] + 1) != 0;
}
//! Writing a quad
bool WriteQuad (const Graphic3d_Vec4i& theQuad)
{
if (myHasNormals)
{
return Fprintf (myFile, "f %d//%d %d//%d %d//%d %d//%d\n",
theQuad[0] + 1, theQuad[0] + 1,
theQuad[1] + 1, theQuad[1] + 1,
theQuad[2] + 1, theQuad[2] + 1,
theQuad[3] + 1, theQuad[3] + 1) != 0;
}
return Fprintf (myFile, "f %d %d %d %d\n",
theQuad[0] + 1,
theQuad[1] + 1,
theQuad[2] + 1,
theQuad[3] + 1) != 0;
}
//! Writing a vector
bool WriteVertex (const Graphic3d_Vec3& theValue)
{
return Fprintf (myFile, "v %f %f %f\n", theValue.x(), theValue.y(), theValue.z()) != 0;
}
//! Writing a vector
bool WriteNormal (const Graphic3d_Vec3& theValue)
{
return Fprintf (myFile, "vn %f %f %f\n", theValue.x(), theValue.y(), theValue.z()) != 0;
}
//! Writing a group name
bool WriteGroup (const TCollection_AsciiString& theValue)
{
return Fprintf (myFile, "g %s\n", theValue.ToCString()) != 0;
}
private:
FILE* myFile;
TCollection_AsciiString myName;
bool myHasNormals;
bool myIsOpened;
};
//================================================================
// Function : Constructor
// Purpose :
//================================================================
ObjDataWriter::ObjDataWriter()
{
//
}
//================================================================
// Function : Write
// Purpose :
//================================================================
Standard_Boolean ObjDataWriter::Write (const Handle(MeshDataSource)& theDataSrc,
const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& /*theProgress*/)
{
if (theDataSrc.IsNull())
{
return Standard_False;
}
// header
/*NCollection_IndexedMap<TCollection_AsciiString> aComments;
for (NCollection_Sequence<TCollection_AsciiString>::Iterator aCommentIter (theDataSrc->FileComments()); aCommentIter.More(); aCommentIter.Next())
{
aComments.Add (aCommentIter.Value());
}
aComments.Add ("Exported by OpenCASCADE CAD Assistant [www.opencascade.com]");*/
Standard_CLocaleSentry aLocaleSentry;
ObjWriter anObjFile (theFile, theDataSrc->HasNormals());
if (!anObjFile.IsOpened()
|| !anObjFile.WriteHeader (theDataSrc->NbNodes(), theDataSrc->NbElements()))
{
return Standard_False;
}
for (Standard_Integer aNodeIter = 0; aNodeIter < theDataSrc->NbNodes(); ++aNodeIter)
{
const Graphic3d_Vec3& aNode = theDataSrc->Nodes().Value (aNodeIter);
if (!anObjFile.WriteVertex (aNode))
{
return Standard_False;
}
}
if (theDataSrc->HasNormals())
{
for (Standard_Integer aNodeIter = 0; aNodeIter < theDataSrc->NbNodes(); ++aNodeIter)
{
const Graphic3d_Vec3& aNormal = theDataSrc->Normals().Value (aNodeIter);
if (!anObjFile.WriteNormal (aNormal))
{
return Standard_False;
}
}
}
for (Standard_Integer anElemIter = 0; anElemIter < theDataSrc->NbElements(); ++anElemIter)
{
const Graphic3d_Vec4i& anElem = theDataSrc->Elements().Value (anElemIter);
if (anElem[3] == -1)
{
if (!anObjFile.WriteTriangle (anElem))
{
return Standard_False;
}
}
else
{
if (!anObjFile.WriteQuad (anElem))
{
return Standard_False;
}
}
}
anObjFile.Close();
return Standard_True;
}
//! Trivial convertor
inline Graphic3d_Vec3 objXyzToVec (const gp_XYZ& thePnt)
{
return Graphic3d_Vec3 ((float )thePnt.X(), (float )thePnt.Y(), (float )thePnt.Z());
}
//================================================================
// Function : Write
// Purpose :
//================================================================
Standard_Boolean ObjDataWriter::Write (const AIS_ListOfInteractive& thePrsList,
const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& /*theProgress*/)
{
if (thePrsList.IsEmpty())
{
return Standard_False;
}
Standard_Integer aNbNodesAll = 0;
Standard_Integer aNbElemsAll = 0;
for (FaceIterator aFaceIter (thePrsList); aFaceIter.More(); aFaceIter.Next())
{
aNbNodesAll += aFaceIter.Triangulation->Nodes().Length();
aNbElemsAll += aFaceIter.Triangulation->Triangles().Length();
}
if (aNbNodesAll == 0
|| aNbElemsAll == 0)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("No mesh data to save!\n"), Message_Fail);
return Standard_False;
}
Standard_CLocaleSentry aLocaleSentry;
ObjWriter anObjFile (theFile, Standard_True);
if (!anObjFile.IsOpened()
|| !anObjFile.WriteHeader (aNbNodesAll, aNbElemsAll))
{
return Standard_False;
}
// write vertices
BRepAdaptor_Surface aFaceAdaptor;
BRepLProp_SLProps aSLTool (1, 1e-12);
gp_Dir aNormal;
Standard_Integer aFirstNode = 0;
Graphic3d_Vec4i aTriNodes (-1, -1, -1, -1);
Standard_Integer aNbFaces = 0;
TCollection_AsciiString aPrevGroup;
for (FaceIterator aFaceIter (thePrsList); aFaceIter.More(); aFaceIter.Next())
{
++aNbFaces;
const Standard_Integer aLower = aFaceIter.Triangulation->Triangles().Lower();
const Standard_Boolean isMirrored = aFaceIter.Trsf.VectorialPart().Determinant() < 0.0;
const Handle(Poly_Triangulation)& aTriangulation = aFaceIter.Triangulation;
TCollection_AsciiString aRefName;
Handle(TDataStd_Name) aNodeName;
if (aFaceIter.ShapePrs->GetLabel().FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
aRefName = TCollection_AsciiString (aNodeName->Get());
}
if (!aRefName.IsEmpty()
&& !aRefName.IsEqual (aPrevGroup)
&& !anObjFile.WriteGroup (aRefName))
{
return Standard_False;
}
// write nodes
const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
const gp_Trsf aTrsf = aFaceIter.Trsf;
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
{
gp_Pnt aNode = aNodes (aNodeIter);
aNode.Transform (aTrsf);
if (!anObjFile.WriteVertex (objXyzToVec (aNode.XYZ())))
{
return Standard_False;
}
}
// write normals
TopoDS_Face aFace = TopoDS::Face (aFaceIter.Face.Oriented (TopAbs_FORWARD));
aFace.Location (TopLoc_Location());
aFaceAdaptor.Initialize (aFace, Standard_False);
aSLTool.SetSurface (aFaceAdaptor);
const TColgp_Array1OfPnt2d& aNodeUVs = aTriangulation->UVNodes();
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
{
const gp_XY& anUV = aNodeUVs.Value (aNodeIter).XY();
aSLTool.SetParameters (anUV.X(), anUV.Y());
gp_Dir aNormal ((aSLTool.IsNormalDefined() ? aSLTool.Normal() : gp::DZ()).XYZ());
aNormal.Transform (aTrsf);
if (aFaceIter.Face.Orientation() == TopAbs_REVERSED)
{
aNormal.Reverse();
}
if (!anObjFile.WriteNormal (objXyzToVec (aNormal.XYZ())))
{
return Standard_False;
}
}
// write indices
for (Poly_Array1OfTriangle::Iterator anElemIter (aFaceIter.Triangulation->Triangles()); anElemIter.More(); anElemIter.Next())
{
if ((aFaceIter.Face.Orientation() == TopAbs_REVERSED) ^ isMirrored)
{
anElemIter.Value().Get (aTriNodes[0], aTriNodes[2], aTriNodes[1]);
}
else
{
anElemIter.Value().Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
}
aTriNodes[0] = aFirstNode + aTriNodes[0] - aLower;
aTriNodes[1] = aFirstNode + aTriNodes[1] - aLower;
aTriNodes[2] = aFirstNode + aTriNodes[2] - aLower;
if (!anObjFile.WriteTriangle (aTriNodes))
{
return Standard_False;
}
}
aFirstNode += aFaceIter.Triangulation->NbNodes();
}
anObjFile.Close();
return Standard_True;
}

View File

@@ -0,0 +1,49 @@
// Copyright (c) 2015 OPEN CASCADE SAS
//
// This file is part of commercial software by OPEN CASCADE SAS.
//
// This software is furnished in accordance with the terms and conditions
// of the contract and with the inclusion of this copyright notice.
// This software or any other copy thereof may not be provided or otherwise
// be made available to any third party.
// No ownership title to the software is transferred hereby.
//
// OPEN CASCADE SAS makes no representation or warranties with respect to the
// performance of this software, and specifically disclaims any responsibility
// for any damages, special or consequential, connected with its use.
#ifndef ObjDataWriter_H
#define ObjDataWriter_H
#include <MeshDataSource.h>
#include <AIS_ListOfInteractive.hxx>
//! Mesh writer to the OBJ format.
class ObjDataWriter : public Standard_Transient
{
public:
//! Empty constructor.
Standard_EXPORT ObjDataWriter();
//! Write the mesh into specified file.
Standard_EXPORT Standard_Boolean Write (const Handle(MeshDataSource)& theDataSrc,
const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress);
//! Write the mesh presentation of the model into specified file.
Standard_EXPORT Standard_Boolean Write (const AIS_ListOfInteractive& thePrsList,
const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress);
public:
DEFINE_STANDARD_RTTIEXT(ObjDataWriter, Standard_Transient)
};
DEFINE_STANDARD_HANDLE(ObjDataWriter, Standard_Transient)
#endif // ObjDataWriter_H

View File

@@ -101,6 +101,7 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio
Graphic3d_ZLayerSettings anUnderlaySettings;
anUnderlaySettings.Flags = 0;
anUnderlaySettings.IsImmediate = false;
anUnderlaySettings.UseEnvironmentTexture = false;
myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, anUnderlaySettings);
@@ -133,6 +134,7 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio
Graphic3d_ZLayerSettings anOsdSettings;
anOsdSettings.Flags = 0;
anOsdSettings.IsImmediate = true;
anOsdSettings.UseEnvironmentTexture = false;
myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, anOsdSettings);

View File

@@ -365,6 +365,14 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
glDepthFunc (GL_ALWAYS);
}
// save environment texture
Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
if (!myLayerSettings.UseEnvironmentTexture)
{
Handle(OpenGl_Texture) anEmptyTexture;
theWorkspace->SetEnvironmentTexture (anEmptyTexture);
}
// handle depth offset
if (IsSettingEnabled (Graphic3d_ZLayerDepthOffset))
{
@@ -390,4 +398,10 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
theWorkspace->SetPolygonOffset (anAppliedOffsetParams.mode,
anAppliedOffsetParams.factor,
anAppliedOffsetParams.units);
// restore environment texture
if (!myLayerSettings.UseEnvironmentTexture)
{
theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
}
}

View File

@@ -23,7 +23,6 @@
#define OPENGL_NS_ANTIALIASING (1<<5)
#define OPENGL_NS_2NDPASSNEED (1<<6)
#define OPENGL_NS_2NDPASSDO (1<<7)
#define OPENGL_NS_FORBIDSETTEX (1<<8)
#define OPENGL_NS_WHITEBACK (1<<9)
#define OPENGL_NS_WHITEBACK (1<<8)
#endif //_OpenGl_NamedStatus_Header

View File

@@ -520,6 +520,18 @@ Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(Ope
return Standard_True;
}
// =======================================================================
// function : OpenGl_RaytraceClipPlanes
// purpose : Creates new set of clipping planes
// =======================================================================
OpenGl_RaytraceClipPlanes::OpenGl_RaytraceClipPlanes()
{
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < MAX_PLANE_NUMBER; ++aPlaneIdx)
{
myClipPlanes[aPlaneIdx * 2] = BVH_Vec4f (-1.f, -1.f, -1.f, -1.f);
}
}
namespace OpenGl_Raytrace
{
// =======================================================================

View File

@@ -223,6 +223,133 @@ private:
};
//! Set of clipping planes specific for OpenGL primitive array.
class OpenGl_RaytraceClipPlanes
{
public:
//! Maximum number of clipping planes used in ray-tracing for each
//! OpenGL primitive array. This is not implementation restriction,
//! but it is reasonable to limit max number of planes in order to
//! simplify GLSL data representation.
static const Standard_Integer MAX_PLANE_NUMBER = 8;
//! State of clipping plane.
enum ClipPlaneState {
CLIP_PLANE_OFF = -1, //!< plane is deactivated
CLIP_PLANE_VIEW = 0, //!< plane is in view space
CLIP_PLANE_WORLD = 1 //!< plane is in world space
};
//! Wrapper for clipping plane configuration.
class ClipPlane
{
public:
//! Creates new clipping plane wrapper.
ClipPlane (BVH_Vec4f& theSettings,
BVH_Vec4f& theEquation) : mySettings (theSettings),
myEquation (theEquation) {}
//! Sets 4D equation vector for clipping plane.
void SetEquation (const BVH_Vec4d& theEquation, const ClipPlaneState theState = CLIP_PLANE_WORLD)
{
for (Standard_Integer anIndex = 0; anIndex < 4; ++anIndex)
{
myEquation[anIndex] = static_cast<Standard_ShortReal> (theEquation[anIndex]);
}
SetState (theState);
}
//! Returns state of clipping plane.
ClipPlaneState State()
{
return static_cast<ClipPlaneState> ((int)mySettings.x());
}
//! Sets state of clipping plane.
void SetState (const ClipPlaneState theState)
{
mySettings.x() = static_cast<Standard_ShortReal> (theState);
}
private:
//! Settings of clipping plane.
BVH_Vec4f& mySettings;
//! 4D equation vector of clipping plane.
BVH_Vec4f& myEquation;
};
public:
//! Creates new set of clipping planes.
OpenGl_RaytraceClipPlanes();
//! Returns clipping plane for the given index.
ClipPlane operator[] (const Standard_Integer theIndex)
{
return ClipPlane (myClipPlanes[theIndex * 2 + 0],
myClipPlanes[theIndex * 2 + 1]);
}
//! Returns packed (serialized) representation of clipping planes set.
const Standard_ShortReal* Packed()
{
return reinterpret_cast<Standard_ShortReal*> (this);
}
private:
//! Serialized clipping planes storage.
BVH_Vec4f myClipPlanes[MAX_PLANE_NUMBER * 2];
};
//! Stores transform properties of ray-tracing object.
class OpenGl_RaytraceTransform : public BVH_Transform<Standard_ShortReal, 4>
{
public:
//! Value of invalid clipping plane set.
static const Standard_Integer NO_CLIPPING = -1;
public:
//! Creates new identity transformation.
OpenGl_RaytraceTransform() : BVH_Transform<Standard_ShortReal, 4>()
{
myClipSetID = NO_CLIPPING; // no clipping by default
}
//! Creates new transformation with specified matrix.
OpenGl_RaytraceTransform (const BVH_Mat4f& theTransform) : BVH_Transform<Standard_ShortReal, 4> (theTransform)
{
myClipSetID = NO_CLIPPING; // no clipping by default
}
//! Returns ID of associated set of clipping planes.
Standard_Integer ClipSetID() const
{
return myClipSetID;
}
//! Sets ID of associated set of clipping planes.
void SetClipSetID (const Standard_Integer theClipSetID)
{
myClipSetID = theClipSetID;
}
protected:
//! ID of associated set of clipping planes.
Standard_Integer myClipSetID;
};
//! Stores geometry of ray-tracing scene.
class OpenGl_RaytraceGeometry : public BVH_Geometry<Standard_ShortReal, 3>
{
@@ -235,7 +362,7 @@ public:
//! This is not restriction of the solution implemented, but
//! rather the reasonable limit of the number of textures in
//! various applications (can be increased if needed).
static const Standard_Integer MAX_TEX_NUMBER = 32;
static const Standard_Integer MAX_TEX_NUMBER = 128;
public:
@@ -247,6 +374,10 @@ public:
std::vector<OpenGl_RaytraceMaterial,
NCollection_StdAllocator<OpenGl_RaytraceMaterial> > Materials;
//! Array of sets of clipping plane parameters.
std::vector<OpenGl_RaytraceClipPlanes,
NCollection_StdAllocator<OpenGl_RaytraceClipPlanes> > ClipPlanes;
//! Global ambient from all light sources.
BVH_Vec4f Ambient;

View File

@@ -824,25 +824,6 @@ const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(Op
return &myMaterialStates.Find (theProgram);
}
// =======================================================================
// function : SurfaceDetailState
// purpose : Returns current state of OCCT surface detail
// =======================================================================
const OpenGl_SurfaceDetailState& OpenGl_ShaderManager::SurfaceDetailState() const
{
return mySurfaceDetailState;
}
// =======================================================================
// function : UpdateSurfaceDetailStateTo
// purpose : Updates state of OCCT surface detail
// =======================================================================
void OpenGl_ShaderManager::UpdateSurfaceDetailStateTo (const Graphic3d_TypeOfSurfaceDetail theDetail)
{
mySurfaceDetailState.Set (theDetail);
mySurfaceDetailState.Update();
}
namespace
{

View File

@@ -19,7 +19,6 @@
#include <Graphic3d_ShaderProgram.hxx>
#include <Graphic3d_StereoMode.hxx>
#include <Graphic3d_TypeOfShadingModel.hxx>
#include <Graphic3d_TypeOfSurfaceDetail.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_Sequence.hxx>
@@ -253,14 +252,6 @@ public:
//! Returns current state of OCCT material for specified program.
Standard_EXPORT const OpenGl_MaterialState* MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
public:
//! Returns current state of OCCT surface detail.
Standard_EXPORT const OpenGl_SurfaceDetailState& SurfaceDetailState() const;
//! Updates state of OCCT surface detail.
Standard_EXPORT void UpdateSurfaceDetailStateTo (const Graphic3d_TypeOfSurfaceDetail theDetail);
public:
//! Pushes current state of OCCT graphics parameters to specified program.
@@ -309,7 +300,7 @@ protected:
{
aBits |= OpenGl_PO_ClipPlanes;
}
if (theEnableEnvMap && mySurfaceDetailState.Detail() == Graphic3d_TOD_ENVIRONMENT)
if (theEnableEnvMap)
{
// Environment map overwrites material texture
aBits |= OpenGl_PO_TextureEnv;
@@ -413,7 +404,6 @@ protected:
OpenGl_WorldViewState myWorldViewState; //!< State of OCCT world-view transformation
OpenGl_ClippingState myClippingState; //!< State of OCCT clipping planes
OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources
OpenGl_SurfaceDetailState mySurfaceDetailState; //!< State of OCCT surface detail
private:

View File

@@ -16,7 +16,6 @@
#ifndef _OpenGl_State_HeaderFile
#define _OpenGl_State_HeaderFile
#include <Graphic3d_TypeOfSurfaceDetail.hxx>
#include <InterfaceGraphic_tgl_all.hxx>
#include <NCollection_List.hxx>
#include <OpenGl_Element.hxx>
@@ -183,28 +182,4 @@ protected:
};
//! Defines generic state of OCCT surface detail.
class OpenGl_SurfaceDetailState : public OpenGl_StateInterface
{
public:
//! Creates new surface detail state.
OpenGl_SurfaceDetailState (const Graphic3d_TypeOfSurfaceDetail theDetail = Graphic3d_TOD_NONE)
: myDetail (theDetail)
{
//
}
//! Sets new surface detail.
void Set (const Graphic3d_TypeOfSurfaceDetail theDetail) { myDetail = theDetail; }
//! Returns surface detail.
Graphic3d_TypeOfSurfaceDetail Detail() const { return myDetail; }
private:
Graphic3d_TypeOfSurfaceDetail myDetail; //!< OCCT surface detail
};
#endif // _OpenGl_State_HeaderFile

View File

@@ -241,6 +241,20 @@ void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
myAspectText->SetAspect (theAspect);
}
// =======================================================================
// function : SetClipPlanes
// purpose :
// =======================================================================
void OpenGl_Structure::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane &thePlanes)
{
Graphic3d_CStructure::SetClipPlanes (thePlanes);
if (IsRaytracable())
{
++myModificationState;
}
}
// =======================================================================
// function : clearHighlightBox
// purpose :

View File

@@ -129,6 +129,9 @@ public:
Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theGlCtx);
//! Pass clip planes to the associated graphic driver structure
void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes);
//! Renders groups of structure without applying any attributes (i.e. transform, material etc).
//! @param theWorkspace current workspace
//! @param theHasClosed flag will be set to TRUE if structure contains at least one group of closed primitives

View File

@@ -66,7 +66,6 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
myAntiAliasing (Standard_False),
myCulling (Standard_True),
myShadingModel (Graphic3d_TOSM_FACET),
mySurfaceDetail (Graphic3d_TOD_ALL),
myBackfacing (Graphic3d_TOBM_AUTOMATIC),
myBgColor (myDefaultBg),
myFog (myDefaultFog),

View File

@@ -34,7 +34,6 @@
#include <Graphic3d_GraduatedTrihedron.hxx>
#include <Graphic3d_SequenceOfHClipPlane.hxx>
#include <Graphic3d_TypeOfShadingModel.hxx>
#include <Graphic3d_TypeOfSurfaceDetail.hxx>
#include <Graphic3d_WorldViewProjState.hxx>
#include <Graphic3d_ZLayerSettings.hxx>
@@ -308,16 +307,6 @@ public:
//! Sets shading model of the view.
virtual void SetShadingModel (const Graphic3d_TypeOfShadingModel theModel) Standard_OVERRIDE { myShadingModel = theModel; }
//! Returns surface detail type of the view.
virtual Graphic3d_TypeOfSurfaceDetail SurfaceDetailType() const Standard_OVERRIDE { return mySurfaceDetail; }
//! Sets surface detail type of the view.
virtual void SetSurfaceDetailType (const Graphic3d_TypeOfSurfaceDetail theType) Standard_OVERRIDE
{
mySurfaceDetail = theType;
myToUpdateEnvironmentMap = Standard_True;
}
//! Return backfacing model used for the view.
virtual Graphic3d_TypeOfBackfacingModel BackfacingModel() const Standard_OVERRIDE { return myBackfacing; }
@@ -562,7 +551,6 @@ protected:
Standard_Boolean myAntiAliasing;
Standard_Boolean myCulling;
Graphic3d_TypeOfShadingModel myShadingModel;
Graphic3d_TypeOfSurfaceDetail mySurfaceDetail;
Graphic3d_TypeOfBackfacingModel myBackfacing;
TEL_COLOUR myBgColor;
OPENGL_FOG myFog;
@@ -673,10 +661,12 @@ protected: //! @name data types related to ray-tracing
OpenGl_RT_uSphereMapForBack,
OpenGl_RT_uTexSamplersArray,
OpenGl_RT_uBlockedRngEnabled,
OpenGl_RT_uMaxRadiance,
// sampled frame params
OpenGl_RT_uSampleWeight,
OpenGl_RT_uFrameRndSeed,
OpenGl_RT_uBilateralEnabled,
// adaptive FSAA params
OpenGl_RT_uOffsetX,
@@ -703,13 +693,14 @@ protected: //! @name data types related to ray-tracing
OpenGl_RT_RaytraceMaterialTexture = 9,
OpenGl_RT_RaytraceLightSrcTexture = 10,
OpenGl_RT_RaytraceClippingTexture = 11,
OpenGl_RT_FsaaInputTexture = 11,
OpenGl_RT_PrevAccumTexture = 12,
OpenGl_RT_DepthTexture = 13,
OpenGl_RT_FsaaInputTexture = 12,
OpenGl_RT_PrevAccumTexture = 13,
OpenGl_RT_DepthTexture = 14,
OpenGl_RT_OpenGlColorTexture = 14,
OpenGl_RT_OpenGlDepthTexture = 15
OpenGl_RT_OpenGlColorTexture = 15,
OpenGl_RT_OpenGlDepthTexture = 16
};
//! Tool class for management of shader sources.
@@ -1037,6 +1028,8 @@ protected: //! @name fields related to ray-tracing
Handle(OpenGl_TextureBufferArb) myRaytraceMaterialTexture;
//! Texture buffer of light source properties.
Handle(OpenGl_TextureBufferArb) myRaytraceLightSrcTexture;
//! Texture buffer of clipping planes parameters.
Handle(OpenGl_TextureBufferArb) myRaytraceClippingTexture;
//! 1st framebuffer (FBO) to perform adaptive FSAA.
Handle(OpenGl_FrameBuffer) myRaytraceFBO1[2];

View File

@@ -403,7 +403,7 @@ Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*
return Standard_True;
}
// Get structure material
// Get material of the structure
OpenGl_RaytraceMaterial aStructMaterial;
if (theStructure->AspectFace() != NULL)
@@ -435,6 +435,45 @@ Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure*
const Graphic3d_Mat4* theTransform,
const Handle(OpenGl_Context)& theGlContext)
{
// ID of clipping plane set
Standard_Integer aClipSetID = -1;
// Collect clipping planes of structure scope
if (!theStructure->ClipPlanes().IsEmpty())
{
NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes;
for (Graphic3d_SequenceOfHClipPlane::Iterator aClipIter (theStructure->ClipPlanes()); aClipIter.More(); aClipIter.Next())
{
const Handle(Graphic3d_ClipPlane)& aClipPlane = aClipIter.Value();
if (aClipPlane->IsOn())
{
if (aUserPlanes.IsNull())
{
aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
}
aUserPlanes->Append (aClipPlane);
}
}
if (!aUserPlanes.IsNull())
{
myRaytraceGeometry.ClipPlanes.push_back (OpenGl_RaytraceClipPlanes());
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < aUserPlanes->Size(); ++aPlaneIdx)
{
if (aPlaneIdx < OpenGl_RaytraceClipPlanes::MAX_PLANE_NUMBER)
{
myRaytraceGeometry.ClipPlanes.back()[aPlaneIdx].SetEquation (aUserPlanes->operator ()(aPlaneIdx + 1)->GetEquation());
}
}
aClipSetID = static_cast<Standard_Integer> (myRaytraceGeometry.ClipPlanes.size() - 1);
}
}
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
{
// Get group material
@@ -476,13 +515,18 @@ Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure*
{
OpenGl_TriangleSet* aSet = aSetIter->second;
BVH_Transform<Standard_ShortReal, 4>* aTransform = new BVH_Transform<Standard_ShortReal, 4>();
OpenGl_RaytraceTransform* aTransform = new OpenGl_RaytraceTransform;
if (theTransform != NULL)
{
aTransform->SetTransform (*theTransform);
}
if (aClipSetID != OpenGl_RaytraceTransform::NO_CLIPPING)
{
aTransform->SetClipSetID (aClipSetID);
}
aSet->SetProperties (aTransform);
if (aSet->MaterialIndex() != OpenGl_TriangleSet::INVALID_MATERIAL && aSet->MaterialIndex() != aMatID)
@@ -492,18 +536,22 @@ Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure*
}
else
{
NCollection_Handle<BVH_Object<Standard_ShortReal, 3> > aSet =
addRaytracePrimitiveArray (aPrimArray, aMatID, 0);
NCollection_Handle<BVH_Object<Standard_ShortReal, 3> > aSet = addRaytracePrimitiveArray (aPrimArray, aMatID, 0);
if (!aSet.IsNull())
{
BVH_Transform<Standard_ShortReal, 4>* aTransform = new BVH_Transform<Standard_ShortReal, 4>;
OpenGl_RaytraceTransform* aTransform = new OpenGl_RaytraceTransform;
if (theTransform != NULL)
{
aTransform->SetTransform (*theTransform);
}
if (aClipSetID != OpenGl_RaytraceTransform::NO_CLIPPING)
{
aTransform->SetClipSetID (aClipSetID);
}
aSet->SetProperties (aTransform);
myRaytraceGeometry.Objects().Append (aSet);
@@ -1478,6 +1526,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
"uRaytraceMaterialTexture", OpenGl_RT_RaytraceMaterialTexture);
aShaderProgram->SetSampler (theGlContext,
"uRaytraceLightSrcTexture", OpenGl_RT_RaytraceLightSrcTexture);
aShaderProgram->SetSampler (theGlContext,
"uRaytraceClippingTexture", OpenGl_RT_RaytraceClippingTexture);
aShaderProgram->SetSampler (theGlContext,
"uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
@@ -1548,6 +1598,8 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
aShaderProgram->GetUniformLocation (theGlContext, "uSphereMapForBack");
myUniformLocations[anIndex][OpenGl_RT_uBlockedRngEnabled] =
aShaderProgram->GetUniformLocation (theGlContext, "uBlockedRngEnabled");
myUniformLocations[anIndex][OpenGl_RT_uMaxRadiance] =
aShaderProgram->GetUniformLocation (theGlContext, "uMaxRadiance");
myUniformLocations[anIndex][OpenGl_RT_uSampleWeight] =
aShaderProgram->GetUniformLocation (theGlContext, "uSampleWeight");
@@ -1562,6 +1614,9 @@ Standard_Boolean OpenGl_View::initRaytraceResources (const Handle(OpenGl_Context
theGlContext->BindProgram (myOutImageProgram);
myUniformLocations[0][OpenGl_RT_uBilateralEnabled] =
myOutImageProgram->GetUniformLocation (theGlContext, "uBilateralEnabled");
myOutImageProgram->SetSampler (theGlContext,
"uInputTexture", OpenGl_RT_PrevAccumTexture);
@@ -1635,6 +1690,7 @@ void OpenGl_View::releaseRaytraceResources (const Handle(OpenGl_Context)& theGlC
nullifyResource (theGlContext, myRaytraceLightSrcTexture);
nullifyResource (theGlContext, myRaytraceMaterialTexture);
nullifyResource (theGlContext, myRaytraceClippingTexture);
myRaytraceGeometry.ReleaseResources (theGlContext);
@@ -1770,7 +1826,7 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
}
/////////////////////////////////////////////////////////////////////////////
// Create OpenGL BVH buffers
// Create BVH buffers
if (mySceneNodeInfoTexture.IsNull()) // create scene BVH buffers
{
@@ -1810,6 +1866,9 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
}
}
/////////////////////////////////////////////////////////////////////////////
// Create material buffer
if (myRaytraceMaterialTexture.IsNull()) // create material buffer
{
myRaytraceMaterialTexture = new OpenGl_TextureBufferArb;
@@ -1817,7 +1876,23 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
if (!myRaytraceMaterialTexture->Create (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffers for material data" << std::endl;
std::cout << "Error: Failed to create buffer for material data" << std::endl;
#endif
return Standard_False;
}
}
/////////////////////////////////////////////////////////////////////////////
// Create clip planes buffer
if (myRaytraceClippingTexture.IsNull()) // create clipping planes buffer
{
myRaytraceClippingTexture = new OpenGl_TextureBufferArb;
if (!myRaytraceClippingTexture->Create (theGlContext))
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to create buffer for clip plane data" << std::endl;
#endif
return Standard_False;
}
@@ -1835,13 +1910,17 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
myRaytraceGeometry.Objects().ChangeValue (anElemIndex).operator->());
const BVH_Transform<Standard_ShortReal, 4>* aTransform =
dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (aTriangleSet->Properties().operator->());
const OpenGl_RaytraceTransform* aTransform =
dynamic_cast<const OpenGl_RaytraceTransform*> (aTriangleSet->Properties().operator->());
Standard_ASSERT_RETURN (aTransform != NULL,
"OpenGl_TriangleSet does not contain transform", Standard_False);
aNodeTransforms[anElemIndex] = aTransform->Inversed();
// Note: write clip plane ID in last matrix component, because
// the last matrix row is not used for transformation purposes
aNodeTransforms[anElemIndex].SetValue (3, 3, aTransform->ClipSetID());
}
aResult &= mySceneTransformTexture->Init (theGlContext, 4,
@@ -2016,6 +2095,23 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
}
}
/////////////////////////////////////////////////////////////////////////////
// Write clip planes buffer
if (myRaytraceGeometry.ClipPlanes.size() != 0)
{
aResult &= myRaytraceClippingTexture->Init (theGlContext, 4,
GLsizei (myRaytraceGeometry.ClipPlanes.size() * 16), myRaytraceGeometry.ClipPlanes.front().Packed());
if (!aResult)
{
#ifdef RAY_TRACE_PRINT_INFO
std::cout << "Error: Failed to upload clipping planes buffer" << std::endl;
#endif
return Standard_False;
}
}
myIsRaytraceDataValid = myRaytraceGeometry.Objects().Size() != 0;
#ifdef RAY_TRACE_PRINT_INFO
@@ -2166,7 +2262,7 @@ Standard_Boolean OpenGl_View::updateRaytraceEnvironmentMap (const Handle(OpenGl_
{
aResult &= theGlContext->BindProgram (aProgram);
if (!myTextureEnv.IsNull() && mySurfaceDetail != Graphic3d_TOD_NONE)
if (!myTextureEnv.IsNull())
{
myTextureEnv->Bind (theGlContext,
GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
@@ -2307,6 +2403,7 @@ void OpenGl_View::bindRaytraceTextures (const Handle(OpenGl_Context)& theGlConte
mySceneTransformTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myRaytraceMaterialTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
myRaytraceLightSrcTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
myRaytraceClippingTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceClippingTexture);
if (!myOpenGlFBO.IsNull())
{
@@ -2331,6 +2428,7 @@ void OpenGl_View::unbindRaytraceTextures (const Handle(OpenGl_Context)& theGlCon
mySceneTransformTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
myRaytraceMaterialTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
myRaytraceLightSrcTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
myRaytraceClippingTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceClippingTexture);
if (!myOpenGlFBO.IsNull())
{
@@ -2396,16 +2494,54 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
myRNG.SetSeed();
}
// Set frame accumulation weight
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
myUniformLocations[0][OpenGl_RT_uMaxRadiance], static_cast<Standard_ShortReal> (myRenderParams.RadianceClampValue));
// Set random number generator seed
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast<Standard_Integer> (myRNG.NextInt() >> 2));
}
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
Standard_Integer aSamplesPerPixel = myRenderParams.SamplesPerPixel;
if (aSamplesPerPixel == 0)
{
// Set frame accumulation weight
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + 1));
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
}
else
{
for (int aPassIndex = 0; aPassIndex < aSamplesPerPixel; ++aPassIndex)
{
aRenderFramebuffer = (myAccumFrames + aPassIndex) % 2 ? myRaytraceFBO1[aFBOIdx] : myRaytraceFBO2[aFBOIdx];
anAccumFramebuffer = (myAccumFrames + aPassIndex) % 2 ? myRaytraceFBO2[aFBOIdx] : myRaytraceFBO1[aFBOIdx];
aRenderFramebuffer->BindBuffer (theGlContext);
anAccumFramebuffer->ColorTexture()->Bind (
theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
// Set frame accumulation weight
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uSampleWeight], 1.f / (myAccumFrames + aPassIndex + 1));
// Set random number generator seed
myRaytraceProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uFrameRndSeed], static_cast<Standard_Integer> (myRNG.NextInt() >> 2));
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
//++myAccumFrames;
glFinish();
}
}
}
else
{
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
++myAccumFrames;
}
if (myRaytraceParameters.GlobalIllumination)
{
@@ -2427,6 +2563,9 @@ Standard_Boolean OpenGl_View::runRaytraceShaders (const Standard_Integer
aRenderFramebuffer->DepthStencilTexture()->Bind (
theGlContext, GL_TEXTURE0 + OpenGl_RT_DepthTexture);
myOutImageProgram->SetUniform (theGlContext,
myUniformLocations[0][OpenGl_RT_uBilateralEnabled], myRenderParams.IsGIFilteringEnabled ? 1 : 0);
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
aRenderFramebuffer->DepthStencilTexture()->Unbind (

View File

@@ -475,7 +475,7 @@ void OpenGl_View::Redraw()
if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
&& myRenderParams.IsGlobalIlluminationEnabled)
{
myAccumFrames++;
myAccumFrames += myRenderParams.SamplesPerPixel;
}
// bind default FBO
@@ -1137,7 +1137,15 @@ void OpenGl_View::renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
// display global trihedron
if (myToShowTrihedron)
{
// disable environment texture
Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
Handle(OpenGl_Texture) anEmptyTexture;
theWorkspace->SetEnvironmentTexture (anEmptyTexture);
myTrihedron.Render (theWorkspace);
// restore environment texture
theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
}
if (myToShowGradTrihedron)
{
@@ -1284,84 +1292,50 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
// Clear status bitfields
myWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
// Update state of surface detail level
myWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
// First pass
myWorkspace->SetEnvironmentTexture (myTextureEnv);
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
myWorkspace->DisableTexture();
// Added PCT for handling of textures
switch (mySurfaceDetail)
// Second pass
if (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
{
case Graphic3d_TOD_NONE:
myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
myWorkspace->DisableTexture();
// Render the view
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
break;
myWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
case Graphic3d_TOD_ENVIRONMENT:
myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
if (myRenderParams.Method != Graphic3d_RM_RAYTRACING)
{
myWorkspace->EnableTexture (myTextureEnv);
}
// Render the view
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
myWorkspace->DisableTexture();
break;
// Remember OpenGl properties
GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
GLint aSaveZbuffFunc;
GLboolean aSaveZbuffWrite;
glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
#if !defined(GL_ES_VERSION_2_0)
glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
#endif
GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
case Graphic3d_TOD_ALL:
// First pass
myWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
// Render the view
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
myWorkspace->DisableTexture();
// Change the properties for second rendering pass
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
// Second pass
if (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
{
myWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
if (myRenderParams.Method != Graphic3d_RM_RAYTRACING)
{
myWorkspace->EnableTexture (myTextureEnv);
}
glDepthFunc (GL_EQUAL);
glDepthMask (GL_FALSE);
glEnable (GL_DEPTH_TEST);
// Remember OpenGl properties
GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
GLint aSaveZbuffFunc;
GLboolean aSaveZbuffWrite;
glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
#if !defined(GL_ES_VERSION_2_0)
glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
#endif
GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
// Render the view
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
myWorkspace->DisableTexture();
// Change the properties for second rendering pass
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
// Restore properties back
glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
if (!wasBlendEnabled)
glDisable (GL_BLEND);
glDepthFunc (GL_EQUAL);
glDepthMask (GL_FALSE);
glEnable (GL_DEPTH_TEST);
myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
// Render the view
renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
myWorkspace->DisableTexture();
// Restore properties back
glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
if (!wasBlendEnabled)
glDisable (GL_BLEND);
glDepthFunc (aSaveZbuffFunc);
glDepthMask (aSaveZbuffWrite);
if (!wasZbuffEnabled)
glDisable (GL_DEPTH_FUNC);
}
break;
glDepthFunc (aSaveZbuffFunc);
glDepthMask (aSaveZbuffWrite);
if (!wasZbuffEnabled)
glDisable (GL_DEPTH_FUNC);
}
// Apply restored view matrix.

View File

@@ -970,12 +970,17 @@ const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean th
updateMaterial (TEL_BACK_MATERIAL);
}
if ((NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
if (AspectFace_set->DoTextureMap())
{
if (AspectFace_set->DoTextureMap())
EnableTexture (AspectFace_set->TextureRes (myGlContext),
AspectFace_set->TextureParams());
}
else
{
if (!myEnvironmentTexture.IsNull())
{
EnableTexture (AspectFace_set->TextureRes (myGlContext),
AspectFace_set->TextureParams());
EnableTexture (myEnvironmentTexture,
myEnvironmentTexture->GetParams());
}
else
{

View File

@@ -236,6 +236,18 @@ public:
return myFrontCulling;
}
//! Sets a new environment texture.
void SetEnvironmentTexture (const Handle(OpenGl_Texture)& theTexture)
{
myEnvironmentTexture = theTexture;
}
//! Returns environment texture.
const Handle(OpenGl_Texture)& EnvironmentTexture() const
{
return myEnvironmentTexture;
}
protected:
void updateMaterial (const int theFlag);
@@ -281,6 +293,8 @@ protected: //! @name fields related to status
OpenGl_AspectFace myAspectFaceHl; //!< Hiddenline aspect
Handle(OpenGl_Texture) myEnvironmentTexture;
public: //! @name type definition
DEFINE_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)

View File

@@ -546,10 +546,6 @@ static Standard_Integer OCC280 (Draw_Interpretor& di, Standard_Integer argc, con
TCollection_AsciiString anOldName = ViewerTest::GetCurrentViewName();
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
if (Draw::Atoi (argv[2]))
{
aViewer->SetDefaultSurfaceDetail (V3d_TEX_ALL);
}
aViewer->SetDefaultTypeOfView (V3d_PERSPECTIVE);
Handle(Aspect_Window) asp = ViewerTest::CurrentView()->Window();
Handle(V3d_View) aNewView = aViewer->CreateView();

View File

@@ -4,16 +4,59 @@ uniform sampler2D uInputTexture;
//! Ray tracing depth image.
uniform sampler2D uDepthTexture;
uniform int uBilateralEnabled;
//! Output pixel color.
out vec4 OutColor;
const float rI = 0.270 * 1.0f; // The intensity radius (in pixels).
const float rL = 1.71 * 0.5f; // The geometric radius (in pixels).
const int WindowSize = 8; // The window size (in pixels).
float gaussian (float theL, float theR)
{
return exp (-theL * theL / (2.0f * theR * theR));
}
vec4 bilateral()
{
// Get the sizes
int aWindow = WindowSize / 2;
vec4 anOutCol = vec4 (0.f, 0.f, 0.f, 0.f);
vec4 aRefCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
float aNorm = 0.f;
// Compute the kernel
for (int i = -aWindow; i <= aWindow; i++)
{
for (int j = -aWindow; j <= aWindow; j++)
{
vec4 aCol = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy) + ivec2 (j, i), 0);
float A = gaussian (distance (aCol, aRefCol), rI);
float B = gaussian (length (vec2(j, i)), rL);
anOutCol += aCol * A * B;
aNorm += A * B;
}
}
return anOutCol * (1.f / aNorm);
}
void main (void)
{
vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
vec4 aColor;
if (bool (uBilateralEnabled))
{
aColor = bilateral();
}
else
{
aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
}
float aDepth = texelFetch (uDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
gl_FragDepth = aDepth;
// apply gamma correction (we use gamma = 2)
OutColor = vec4 (sqrt (aColor.rgb), aColor.a);
}
}

View File

@@ -247,7 +247,7 @@ void transmitted (in float theIndex, in vec3 theIncident, out vec3 theTransmit)
//=======================================================================
float handleLambertianReflection (in vec3 theInput, in vec3 theOutput)
{
return max (0.f, theInput.z) * (1.f / M_PI);
return abs (theInput.z) * (1.f / M_PI);
}
//=======================================================================
@@ -298,7 +298,7 @@ vec3 handleBlinnReflection (in vec3 theInput, in vec3 theOutput, in vec3 theFres
vec3 handleMaterial (in SMaterial theMaterial, in vec3 theInput, in vec3 theOutput)
{
return theMaterial.Kd.rgb * handleLambertianReflection (theInput, theOutput) +
theMaterial.Ks.rgb * handleBlinnReflection (theInput, theOutput, theMaterial.Fresnel, theMaterial.Ks.w);
theMaterial.Ks.rgb * handleBlinnReflection (theInput, theOutput, theMaterial.Fresnel, theMaterial.Ks.w);
}
//=======================================================================
@@ -698,10 +698,15 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),
dot (aTrsfRow2, aTexCoord));
vec3 aTexColor = textureLod (
sampler2D (uTextureSamplers[int (aMaterial.Kd.w)]), aTexCoord.st, 0.f).rgb;
vec4 aTexColor = textureLod (
sampler2D (uTextureSamplers[int (aMaterial.Kd.w)]), aTexCoord.st, 0.f);
aMaterial.Kd.rgb *= aTexColor;
aMaterial.Kd.rgb *= aTexColor.rgb * aTexColor.a;
if (aTexColor.a < 1.f)
{
aMaterial.Kt = 0.8f * vec3 (1.f - aTexColor.a);
}
}
#endif
@@ -783,8 +788,8 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
anInput = normalize (fromLocalSpace (anInput, aSpace));
theRay = SRay (theRay.Origin + anInput * uSceneEpsilon +
aHit.Normal * mix (-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, anInput))), anInput);
theRay = SRay (theRay.Origin + anInput * uSceneEpsilon, anInput);// +
//aHit.Normal * mix (-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, anInput))), anInput);
theInverse = InverseDirection (anInput);

View File

@@ -63,6 +63,9 @@ uniform isamplerBuffer uGeometryTriangTexture;
uniform samplerBuffer uRaytraceMaterialTexture;
//! Texture buffer of light source properties.
uniform samplerBuffer uRaytraceLightSrcTexture;
//! Texture buffer of clipping planes properties.
uniform samplerBuffer uRaytraceClippingTexture;
//! Environment map texture.
uniform sampler2D uEnvironmentMapTexture;
@@ -378,12 +381,20 @@ struct SSubTree
ivec4 SubData;
};
#define EMPTY_ROOT ivec4(0)
#define TRS_OFFSET(treelet) treelet.SubData.x
#define BVH_OFFSET(treelet) treelet.SubData.y
#define VRT_OFFSET(treelet) treelet.SubData.z
#define TRG_OFFSET(treelet) treelet.SubData.w
#define EMPTY_ROOT ivec4(0)
#define MAX_CLIP_PLANES 1
#define IS_PLANE_ACTIVE(params) (params.x != -1.F)
#define IS_PLANE_HIDDEN(params) (params.x == -1.F)
#define PLANE_SETTINGS(trsf, index) (16 * int(trsf.w) + 2 * index + 0)
#define PLANE_EQUATION(trsf, index) (16 * int(trsf.w) + 2 * index + 1)
// =======================================================================
// function : SceneNearestHit
@@ -399,6 +410,9 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
SSubTree aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);
float aClipMax = MAXFLOAT;
float aClipMin = -MAXFLOAT;
for (bool toContinue = true; toContinue;)
{
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
@@ -475,7 +489,7 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
float aTime = IntersectTriangle (aSubTree.TrsfRay,
aPoint0, aPoint1, aPoint2, aParams, aNormal);
if (aTime < theHit.Time)
if (aTime > aClipMin && aTime < aClipMax && aTime < theHit.Time)
{
aTriIndex = aTriangle;
@@ -496,13 +510,34 @@ ivec4 SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theH
}
else if (aData.x > 0) // switch node
{
aSubTree.SubData = ivec4 (4 * aData.x - 4, aData.yzw); // store BVH sub-root
aClipMax = MAXFLOAT;
aClipMin = -MAXFLOAT;
aSubTree.SubData = ivec4 (aData.x * 4 - 4, aData.yzw); // store BVH sub-root
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 0);
vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 1);
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 2);
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 3);
for (int aPlaneIdx = 0; aInvTransf3.w >= 0.0 && aPlaneIdx < MAX_CLIP_PLANES; ++aPlaneIdx)
{
vec4 aSettings = texelFetch (uRaytraceClippingTexture, PLANE_SETTINGS (aInvTransf3, aPlaneIdx));
vec4 aEquation = texelFetch (uRaytraceClippingTexture, PLANE_EQUATION (aInvTransf3, aPlaneIdx));
float aNdotD = -dot (aEquation.xyz, theRay.Direct);
if (IS_PLANE_ACTIVE (aSettings))
{
float aPlaneTime = (dot (aEquation.xyz, theRay.Origin) + aEquation.w) / aNdotD;
if (aNdotD < 0.0)
aClipMin = max (aClipMin, aPlaneTime);
else
aClipMax = min (aClipMax, aPlaneTime);
}
}
aSubTree.TrsfRay.Direct = MatrixColMultiplyDir (theRay.Direct,
aInvTransf0,
aInvTransf1,
@@ -540,6 +575,9 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
SSubTree aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);
float aClipMax = MAXFLOAT;
float aClipMin = -MAXFLOAT;
for (bool toContinue = true; toContinue;)
{
ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);
@@ -617,12 +655,12 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
aPoint0, aPoint1, aPoint2, aParams, aNormal);
#ifdef TRANSPARENT_SHADOWS
if (aTime < theDistance)
if (aTime > aClipMin && aTime < aClipMax && aTime < theDistance)
{
aFactor *= 1.f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;
}
#else
if (aTime < theDistance)
if (aTime > aClipMin && aTime < aClipMax && aTime < theDistance)
{
aFactor = 0.f;
}
@@ -640,6 +678,9 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
}
else if (aData.x > 0) // switch node
{
aClipMax = MAXFLOAT;
aClipMin = -MAXFLOAT;
aSubTree.SubData = ivec4 (4 * aData.x - 4, aData.yzw); // store BVH sub-root
vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 0);
@@ -647,6 +688,24 @@ float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)
vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 2);
vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 3);
for (int aPlaneIdx = 0; aInvTransf3.w >= 0.0 && aPlaneIdx < MAX_CLIP_PLANES; ++aPlaneIdx)
{
vec4 aSettings = texelFetch (uRaytraceClippingTexture, PLANE_SETTINGS (aInvTransf3, aPlaneIdx));
vec4 aEquation = texelFetch (uRaytraceClippingTexture, PLANE_EQUATION (aInvTransf3, aPlaneIdx));
float aNdotD = -dot (aEquation.xyz, theRay.Direct);
if (IS_PLANE_ACTIVE (aSettings))
{
float aPlaneTime = (dot (aEquation.xyz, theRay.Origin) + aEquation.w) / aNdotD;
if (aNdotD < 0.0)
aClipMin = max (aClipMin, aPlaneTime);
else
aClipMax = min (aClipMax, aPlaneTime);
}
}
aSubTree.TrsfRay.Direct = MatrixColMultiplyDir (theRay.Direct,
aInvTransf0,
aInvTransf1,

View File

@@ -13,7 +13,8 @@ uniform sampler2D uAccumTexture;
//! Increases performance up to 4 times, but noise becomes structured.
uniform int uBlockedRngEnabled;
#define MAX_RADIANCE vec3 (10.f)
//! Maximum value for radiance clamping.
uniform float uMaxRadiance;
// =======================================================================
// function : main
@@ -46,7 +47,7 @@ void main (void)
aColor.rgb = ZERO;
}
aColor.rgb = min (aColor.rgb, MAX_RADIANCE);
aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
#else

View File

@@ -4,3 +4,5 @@ TKService
TKernel
TKG3d
TKG2d
TKXCAF
TKLCAF

View File

@@ -1,4 +1,6 @@
TKGeomBase
TKXCAF
TKLCAF
TKFillet
TKBRep
TKTopAlgo
@@ -15,6 +17,7 @@ TKTopTest
TKG3d
TKOffset
TKMesh
TKMeshVS
TKV3d
TKDraw
TKOpenGl

View File

@@ -31,7 +31,6 @@ V3d_TypeOfPickCamera.hxx
V3d_TypeOfPickLight.hxx
V3d_TypeOfRepresentation.hxx
V3d_TypeOfShadingModel.hxx
V3d_TypeOfSurfaceDetail.hxx
V3d_TypeOfUpdate.hxx
V3d_TypeOfView.hxx
V3d_TypeOfVisualization.hxx

View File

@@ -1,31 +0,0 @@
// Created on: 1992-11-13
// Created by: GG
// Copyright (c) 1992-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.
#ifndef _V3d_TypeOfSurfaceDetail_HeaderFile
#define _V3d_TypeOfSurfaceDetail_HeaderFile
//! Modes of visualization for objects in a view
//! - V3d_TEX_NONE: no texture mapping,
//! - V3d_TEX_ENVIRONMENT: environment mapping only,
//! - V3d_TEX_ALL: environment and texture mapping.
enum V3d_TypeOfSurfaceDetail
{
V3d_TEX_NONE,
V3d_TEX_ENVIRONMENT,
V3d_TEX_ALL
};
#endif // _V3d_TypeOfSurfaceDetail_HeaderFile

View File

@@ -159,7 +159,6 @@ V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView th
SetAxis (0.,0.,0.,1.,1.,1.);
SetVisualization (theViewer->DefaultVisualization());
SetShadingModel (theViewer->DefaultShadingModel());
SetSurfaceDetail (theViewer->DefaultSurfaceDetail());
SetTwist (0.);
SetAt (0.,0.,0.);
SetProj (theViewer->DefaultViewProj());
@@ -625,15 +624,6 @@ void V3d_View::SetShadingModel (const V3d_TypeOfShadingModel theShadingModel)
myView->SetShadingModel (static_cast<Graphic3d_TypeOfShadingModel> (theShadingModel));
}
//=============================================================================
//function : SetSurfaceDetail
//purpose :
//=============================================================================
void V3d_View::SetSurfaceDetail (const V3d_TypeOfSurfaceDetail theSurfaceDetail)
{
myView->SetSurfaceDetailType (static_cast<Graphic3d_TypeOfSurfaceDetail> (theSurfaceDetail));
}
//=============================================================================
//function : SetTextureEnv
//purpose :
@@ -2421,15 +2411,6 @@ V3d_TypeOfShadingModel V3d_View::ShadingModel() const
return static_cast<V3d_TypeOfShadingModel> (myView->ShadingModel());
}
//=============================================================================
//function : SurfaceDetail
//purpose :
//=============================================================================
V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
{
return static_cast<V3d_TypeOfSurfaceDetail> (myView->SurfaceDetailType());
}
//=============================================================================
//function : TextureEnv
//purpose :

View File

@@ -75,7 +75,6 @@
#include <V3d_TypeOfBackfacingModel.hxx>
#include <V3d_TypeOfOrientation.hxx>
#include <V3d_TypeOfShadingModel.hxx>
#include <V3d_TypeOfSurfaceDetail.hxx>
#include <V3d_TypeOfView.hxx>
#include <V3d_TypeOfVisualization.hxx>
#include <V3d_TypeOfZclipping.hxx>
@@ -260,9 +259,6 @@ public:
//! Defines the shading model for the visualization. Various models are available.
Standard_EXPORT void SetShadingModel (const V3d_TypeOfShadingModel theShadingModel);
//! Selects the kind of rendering for texture mapping. No texture mapping by default.
Standard_EXPORT void SetSurfaceDetail (const V3d_TypeOfSurfaceDetail theSurfaceDetail);
//! Sets the environment texture to use. No environment texture by default.
Standard_EXPORT void SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture);
@@ -721,8 +717,6 @@ public:
//! Returns the current shading model.
Standard_EXPORT V3d_TypeOfShadingModel ShadingModel() const;
Standard_EXPORT V3d_TypeOfSurfaceDetail SurfaceDetail() const;
Standard_EXPORT Handle(Graphic3d_TextureEnv) TextureEnv() const;
//! Returns the current visualisation mode.

View File

@@ -48,8 +48,7 @@ V3d_Viewer::V3d_Viewer (const Handle(Graphic3d_GraphicDriver)& theDriver,
const V3d_TypeOfShadingModel theShadingModel,
const V3d_TypeOfUpdate theUpdateMode,
const Standard_Boolean theComputedMode,
const Standard_Boolean theDefaultComputedMode,
const V3d_TypeOfSurfaceDetail theSurfaceDetail)
const Standard_Boolean theDefaultComputedMode)
:myNextCount (-1),
myDriver (theDriver),
myName (TCollection_ExtendedString (theName)),
@@ -78,7 +77,6 @@ myZLayerGenId (1, IntegerLast())
SetDefaultBackgroundColor (theViewBackground);
SetDefaultVisualization (theVisualization);
SetDefaultShadingModel (theShadingModel);
SetDefaultSurfaceDetail (theSurfaceDetail);
SetDefaultAngle (M_PI / 2.);
SetDefaultTypeOfView (V3d_ORTHOGRAPHIC);
@@ -319,11 +317,6 @@ void V3d_Viewer::SetDefaultShadingModel(const V3d_TypeOfShadingModel Type) {
MyShadingModel = Type ;
}
void V3d_Viewer::SetDefaultSurfaceDetail(const V3d_TypeOfSurfaceDetail Type) {
MySurfaceDetail = Type ;
}
void V3d_Viewer::SetDefaultAngle(const Quantity_PlaneAngle Angle) {
MyDefaultAngle = Angle;
}
@@ -372,10 +365,6 @@ V3d_TypeOfShadingModel V3d_Viewer::DefaultShadingModel() const {
return MyShadingModel ;
}
V3d_TypeOfSurfaceDetail V3d_Viewer::DefaultSurfaceDetail() const {
return MySurfaceDetail ;
}
Quantity_PlaneAngle V3d_Viewer::DefaultAngle() const {
return MyDefaultAngle;
}

View File

@@ -48,7 +48,6 @@
#include <V3d_ListOfTransient.hxx>
#include <V3d_TypeOfOrientation.hxx>
#include <V3d_TypeOfShadingModel.hxx>
#include <V3d_TypeOfSurfaceDetail.hxx>
#include <V3d_TypeOfUpdate.hxx>
#include <V3d_TypeOfView.hxx>
#include <V3d_TypeOfVisualization.hxx>
@@ -91,7 +90,7 @@ public:
//! This limitation might be addressed in some future OCCT releases.
//! If the size of the view is <= 0
//! Warning: Client must creates a graphic driver
Standard_EXPORT V3d_Viewer(const Handle(Graphic3d_GraphicDriver)& theDriver, const Standard_ExtString theName, const Standard_CString theDomain = "", const Quantity_Length theViewSize = 1000.0, const V3d_TypeOfOrientation theViewProj = V3d_XposYnegZpos, const Quantity_NameOfColor theViewBackground = Quantity_NOC_GRAY30, const V3d_TypeOfVisualization theVisualization = V3d_ZBUFFER, const V3d_TypeOfShadingModel theShadingModel = V3d_GOURAUD, const V3d_TypeOfUpdate theUpdateMode = V3d_WAIT, const Standard_Boolean theComputedMode = Standard_True, const Standard_Boolean theDefaultComputedMode = Standard_True, const V3d_TypeOfSurfaceDetail theSurfaceDetail = V3d_TEX_NONE);
Standard_EXPORT V3d_Viewer(const Handle(Graphic3d_GraphicDriver)& theDriver, const Standard_ExtString theName, const Standard_CString theDomain = "", const Quantity_Length theViewSize = 1000.0, const V3d_TypeOfOrientation theViewProj = V3d_XposYnegZpos, const Quantity_NameOfColor theViewBackground = Quantity_NOC_GRAY30, const V3d_TypeOfVisualization theVisualization = V3d_ZBUFFER, const V3d_TypeOfShadingModel theShadingModel = V3d_GOURAUD, const V3d_TypeOfUpdate theUpdateMode = V3d_WAIT, const Standard_Boolean theComputedMode = Standard_True, const Standard_Boolean theDefaultComputedMode = Standard_True);
//! creates a view in the viewer according to its
//! default parameters.
@@ -179,9 +178,6 @@ public:
//! Gives the default type of SHADING.
Standard_EXPORT void SetDefaultShadingModel (const V3d_TypeOfShadingModel Type);
//! Gives the default type of texture mapping.
Standard_EXPORT void SetDefaultSurfaceDetail (const V3d_TypeOfSurfaceDetail Type);
Standard_EXPORT void SetDefaultAngle (const Quantity_PlaneAngle Angle);
//! Defines the mode of regenerating the views making
@@ -240,9 +236,6 @@ public:
//! Returns the default type of Shading
Standard_EXPORT V3d_TypeOfShadingModel DefaultShadingModel() const;
//! Returns the default type of texture mapping
Standard_EXPORT V3d_TypeOfSurfaceDetail DefaultSurfaceDetail() const;
Standard_EXPORT Quantity_PlaneAngle DefaultAngle() const;
//! Returns the regeneration mode of views in the viewer.
@@ -489,7 +482,6 @@ private:
V3d_TypeOfOrientation MyViewProj;
V3d_TypeOfVisualization MyVisualization;
V3d_TypeOfShadingModel MyShadingModel;
V3d_TypeOfSurfaceDetail MySurfaceDetail;
Quantity_PlaneAngle MyDefaultAngle;
V3d_TypeOfView MyDefaultTypeOfView;
Graphic3d_RenderingParams myDefaultRenderingParams;

View File

@@ -3201,8 +3201,6 @@ Standard_Integer VTexture (Draw_Interpretor& theDi, Standard_Integer theArgsNb,
Standard_Integer aPreviousMode = 0;
ViewerTest::CurrentView()->SetSurfaceDetail (V3d_TEX_ALL);
TCollection_AsciiString aShapeName (theArgv[1]);
Handle(AIS_InteractiveObject) anIO;
@@ -3898,125 +3896,6 @@ static int VPerf(Draw_Interpretor& di, Standard_Integer , const char** argv) {
return 0;
}
//==================================================================================
// Function : VAnimation
//==================================================================================
static int VAnimation (Draw_Interpretor& di, Standard_Integer argc, const char** argv) {
if (argc != 5) {
di<<"Use: "<<argv[0]<<" CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile\n";
return 1;
}
Standard_Real thread = 4;
Standard_Real angleA=0;
Standard_Real angleB;
Standard_Real X;
gp_Ax1 Ax1(gp_Pnt(0,0,0),gp_Vec(0,0,1));
BRep_Builder B;
TopoDS_Shape CrankArm;
TopoDS_Shape CylinderHead;
TopoDS_Shape Propeller;
TopoDS_Shape EngineBlock;
//BRepTools::Read(CrankArm,"/dp_26/Indus/ege/assemblage/CrankArm.rle",B);
//BRepTools::Read(CylinderHead,"/dp_26/Indus/ege/assemblage/CylinderHead.rle",B);
//BRepTools::Read(Propeller,"/dp_26/Indus/ege/assemblage/Propeller.rle",B);
//BRepTools::Read(EngineBlock,"/dp_26/Indus/ege/assemblage/EngineBlock.rle",B);
BRepTools::Read(CrankArm,argv[1],B);
BRepTools::Read(CylinderHead,argv[2],B);
BRepTools::Read(Propeller,argv[3],B);
BRepTools::Read(EngineBlock,argv[4],B);
if (CrankArm.IsNull() || CylinderHead.IsNull() || Propeller.IsNull() || EngineBlock.IsNull()) {di<<" Syntaxe error:loading failure.\n";}
OSD_Timer myTimer;
myTimer.Start();
Handle(AIS_Shape) myAisCylinderHead = new AIS_Shape (CylinderHead);
Handle(AIS_Shape) myAisEngineBlock = new AIS_Shape (EngineBlock);
Handle(AIS_Shape) myAisCrankArm = new AIS_Shape (CrankArm);
Handle(AIS_Shape) myAisPropeller = new AIS_Shape (Propeller);
GetMapOfAIS().Bind(myAisCylinderHead,"a");
GetMapOfAIS().Bind(myAisEngineBlock,"b");
GetMapOfAIS().Bind(myAisCrankArm,"c");
GetMapOfAIS().Bind(myAisPropeller,"d");
myAisCylinderHead->SetMutable (Standard_True);
myAisEngineBlock ->SetMutable (Standard_True);
myAisCrankArm ->SetMutable (Standard_True);
myAisPropeller ->SetMutable (Standard_True);
TheAISContext()->SetColor (myAisCylinderHead, Quantity_NOC_INDIANRED);
TheAISContext()->SetColor (myAisEngineBlock, Quantity_NOC_RED);
TheAISContext()->SetColor (myAisPropeller, Quantity_NOC_GREEN);
TheAISContext()->Display (myAisCylinderHead, Standard_False);
TheAISContext()->Display (myAisEngineBlock, Standard_False);
TheAISContext()->Display (myAisCrankArm, Standard_False);
TheAISContext()->Display (myAisPropeller, Standard_False);
TheAISContext()->Deactivate(myAisCylinderHead);
TheAISContext()->Deactivate(myAisEngineBlock );
TheAISContext()->Deactivate(myAisCrankArm );
TheAISContext()->Deactivate(myAisPropeller );
// Boucle de mouvement
for (Standard_Real myAngle = 0;angleA<2*M_PI*10.175 ;myAngle++) {
angleA = thread*myAngle*M_PI/180;
X = Sin(angleA)*3/8;
angleB = atan(X / Sqrt(-X * X + 1));
Standard_Real decal(25*0.6);
//Build a transformation on the display
gp_Trsf aPropellerTrsf;
aPropellerTrsf.SetRotation(Ax1,angleA);
TheAISContext()->SetLocation(myAisPropeller,aPropellerTrsf);
gp_Ax3 base(gp_Pnt(3*decal*(1-Cos(angleA)),-3*decal*Sin(angleA),0),gp_Vec(0,0,1),gp_Vec(1,0,0));
gp_Trsf aCrankArmTrsf;
aCrankArmTrsf.SetTransformation( base.Rotated(gp_Ax1(gp_Pnt(3*decal,0,0),gp_Dir(0,0,1)),angleB));
TheAISContext()->SetLocation(myAisCrankArm,aCrankArmTrsf);
TheAISContext()->UpdateCurrentViewer();
}
TopoDS_Shape myNewCrankArm =myAisCrankArm ->Shape().Located( myAisCrankArm ->Transformation() );
TopoDS_Shape myNewPropeller =myAisPropeller->Shape().Located( myAisPropeller->Transformation() );
myAisCrankArm ->ResetTransformation();
myAisPropeller->ResetTransformation();
myAisCrankArm -> Set(myNewCrankArm );
myAisPropeller -> Set(myNewPropeller);
TheAISContext()->Activate(myAisCylinderHead,0);
TheAISContext()->Activate(myAisEngineBlock,0 );
TheAISContext()->Activate(myAisCrankArm ,0 );
TheAISContext()->Activate(myAisPropeller ,0 );
myTimer.Stop();
myTimer.Show();
myTimer.Start();
TheAISContext()->Redisplay(myAisCrankArm ,Standard_False);
TheAISContext()->Redisplay(myAisPropeller,Standard_False);
TheAISContext()->UpdateCurrentViewer();
a3DView()->Redraw();
myTimer.Stop();
myTimer.Show();
return 0;
}
//==============================================================================
//function : VShading
//purpose : Sharpen or roughten the quality of the shading
@@ -5148,6 +5027,9 @@ static Standard_Integer vr(Draw_Interpretor& , Standard_Integer , const char** a
return 0;
}
#include <MeshPresentation.h>
#include <MeshVS_Drawer.hxx>
#include <MeshVS_DrawerAttribute.hxx>
//===============================================================================================
//function : VBsdf
//purpose :
@@ -5203,7 +5085,17 @@ static int VBsdf (Draw_Interpretor& theDi,
}
Handle(AIS_InteractiveObject) anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
Graphic3d_MaterialAspect aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
Graphic3d_MaterialAspect aMaterial;
Handle(MeshPresentation) aMeshPrs = Handle(MeshPresentation)::DownCast (anIObj);
if (aMeshPrs.IsNull())
{
aMaterial = anIObj->Attributes()->ShadingAspect()->Material();
}
else
{
aMeshPrs->GetDrawer()->GetMaterial(MeshVS_DA_FrontMaterial, aMaterial);
}
Graphic3d_BSDF aBSDF = aMaterial.BSDF();
if (aCmd.HasOption ("print"))
@@ -5507,6 +5399,283 @@ static int VAutoActivateSelection (Draw_Interpretor& theDi,
return 0;
}
#include <ObjDataSource.h>
#include <MeshPresentation.h>
#include <MeshVS_Drawer.hxx>
#include <MeshPrsBuilder.h>
#include <MeshVS_MeshPrsBuilder.hxx>
#include <MeshVS_DrawerAttribute.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
namespace
{
std::vector<TCollection_AsciiString> Split (const TCollection_AsciiString& pSource,
const TCollection_AsciiString& pSeparator)
{
std::vector<TCollection_AsciiString> result;
TCollection_AsciiString token;
const Standard_Integer aSize = pSource.Length();
unsigned int previousPos = 1;
unsigned int currentPos = 1;
while ((currentPos = pSource.FirstLocationInSet(pSeparator, currentPos, aSize)) != 0)
{
result.push_back(pSource.SubString(previousPos, currentPos - previousPos));
previousPos = ++currentPos;
}
// Save last element.
result.push_back(pSource.SubString(previousPos, aSize));
return result;
}
//! Returns true for grayscale properties.
inline bool isGrayscaleProperty (const TCollection_AsciiString& theName)
{
return theName == "intensity";
}
Handle(MeshPresentation) createMeshPresentation (const Handle(MeshDataSource)& theDataSource,
const TCollection_AsciiString& theEntry,
TCollection_AsciiString& theSelEntry,
Handle(MeshScalarProperty)& theSelProperty)
{
theSelEntry.Clear();
theSelProperty.Nullify();
if (theDataSource.IsNull())
{
return Handle(MeshPresentation)();
}
theSelEntry = theEntry;
if (theEntry.IsEmpty())
{
if (theDataSource->HasTexture())
{
theSelEntry = "ply_textured";
}
else if (theDataSource->HasNodalColors())
{
theSelEntry = "ply_colored";
}
/*else if (theDataSource->HasNormals())
{
theSelEntry = "ply_smoothshaded";
}*/
else
{
theSelEntry = "ply_smoothshaded";
//theSelEntry = "ply_shaded";
}
}
std::cout << theSelEntry << std::endl;
Handle(MeshPresentation) aMesh = new MeshPresentation();
Handle(MeshVS_Drawer) aDrawer = aMesh->GetDrawer();
aDrawer->SetBoolean(MeshVS_DA_ShowEdges, Standard_False);
aDrawer->SetBoolean(MeshVS_DA_SmoothShading, theDataSource->HasNormals());
aMesh->SetDataSource(theDataSource);
aMesh->SetMaterial(Graphic3d_NOM_PLASTIC); // myMatAspect
if (theSelEntry == "ply_textured")
{
//myPrsCaps |= DisplayCaps_Texture;
aDrawer->SetBoolean(MeshVS_DA_SmoothShading, Standard_True);
aDrawer->SetColor(MeshVS_DA_InteriorColor, Quantity_NOC_GRAY65);
Handle(MeshPrsBuilder) aBuilder = new MeshPrsBuilder(aMesh, MeshVS_DMF_Shading);
aBuilder->SetMapTextures(Standard_True);
aMesh->AddBuilder(aBuilder, Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_Shading);
}
else if (theSelEntry == "ply_colored")
{
//myPrsCaps |= DisplayCaps_VertColor;
aDrawer->SetBoolean(MeshVS_DA_ColorReflection, Standard_True);
Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(aMesh, MeshVS_DMF_NodalColorDataPrs);
theDataSource->FillNodalColorsBuilder(aBuilder);
aMesh->AddBuilder(aBuilder, Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_NodalColorDataPrs);
}
else if (theSelEntry == "ply_wireframe")
{
aMesh->AddBuilder(new MeshVS_MeshPrsBuilder(aMesh.operator->()), Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_WireFrame);
}
else if (theSelEntry == "ply_smoothshaded")
{
aDrawer->SetBoolean(MeshVS_DA_SmoothShading, Standard_True);
aDrawer->SetColor(MeshVS_DA_InteriorColor, Quantity_NOC_GRAY65);
Handle(MeshPrsBuilder) aBuilder = new MeshPrsBuilder(aMesh, MeshVS_DMF_Shading);
aBuilder->SetMapTextures(Standard_False);
aMesh->AddBuilder(aBuilder, Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_Shading);
}
else if (theSelEntry == "ply_shaded")
{
aDrawer->SetColor(MeshVS_DA_InteriorColor, Quantity_NOC_GRAY65);
aDrawer->SetBoolean(MeshVS_DA_SmoothShading, Standard_False);
aMesh->AddBuilder(new MeshVS_MeshPrsBuilder(aMesh.operator->()), Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_Shading);
}
else if (theSelEntry == "ply_shrink")
{
aDrawer->SetColor(MeshVS_DA_InteriorColor, Quantity_NOC_GRAY65);
aMesh->AddBuilder(new MeshVS_MeshPrsBuilder(aMesh.operator->()), Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_Shrink);
}
//else if (theSelEntry.startsWith("ply_group_nodalprops\n"))
else if (theSelEntry.Search("ply_group_nodalprops\n") != -1)
{
//myPrsCaps |= DisplayCaps_Texture;
std::vector<TCollection_AsciiString> aList = Split(theEntry, "\n");
const int aPropIndex = aList.size() != 2 ? 0 : aList.back().IntegerValue();
theSelProperty = theDataSource->NodalQuantities().Value(aPropIndex);
const Standard_Boolean isGrayscale = isGrayscaleProperty(theSelProperty->Name());
const Standard_Integer aMeshEdgesLimit = 100000;
if (!isGrayscale
&& (aMeshEdgesLimit < 0 || theDataSource->NbNodes() <= aMeshEdgesLimit))
{
aDrawer->SetBoolean(MeshVS_DA_ShowEdges, Standard_True);
}
aDrawer->SetBoolean(MeshVS_DA_ColorReflection, Standard_True);
Handle(MeshPrsBuilder) aBuilder = new MeshPrsBuilder(aMesh, MeshVS_DMF_NodalColorDataPrs);
aBuilder->SetProperty(theSelProperty, Standard_False);
aBuilder->SetGrayscale(isGrayscale);
aMesh->AddBuilder(aBuilder, Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_NodalColorDataPrs);
}
//else if (theSelEntry.startsWith("ply_group_elemprops\n"))
else if (theSelEntry.Search("ply_group_elemprops\n") != -1)
{
//myPrsCaps |= DisplayCaps_Texture;
std::vector<TCollection_AsciiString> aList = Split(theEntry, "\n");
const int aPropIndex = aList.size() != 2 ? 0 : aList.back().IntegerValue();
aDrawer->SetBoolean(MeshVS_DA_ColorReflection, Standard_True);
theSelProperty = theDataSource->ElementalQuantities().Value(aPropIndex);
Handle(MeshPrsBuilder) aBuilder = new MeshPrsBuilder(aMesh, MeshVS_DMF_ElementalColorDataPrs);
aBuilder->SetProperty(theSelProperty, Standard_True);
aBuilder->SetGrayscale(isGrayscaleProperty(theSelProperty->Name()));
aMesh->AddBuilder(aBuilder, Standard_True);
aMesh->SetDisplayMode(MeshVS_DMF_ElementalColorDataPrs);
}
return aMesh;
}
}
// =============================================================================
// function : VDisplayObj
// purpose :
// =============================================================================
static int VDisplayObj (Draw_Interpretor& theDi,
Standard_Integer theArgNb,
const char** theArgVec)
{
if (theArgNb < 3)
{
theDi << theArgVec[0] << "Error: wrong number of arguments.\n";
return 1;
}
const TCollection_AsciiString aName (theArgVec[1]);
const TCollection_AsciiString aPath (theArgVec[2]);
if (GetMapOfAIS().IsBound2(aName))
{
theDi << aName << "already exist.\n";
return 1;
}
Handle(ObjDataSource) aLoader = new ObjDataSource();
Standard_Boolean aResult = aLoader->Read (aPath, NULL, -1, -1);
if (!aResult)
{
theDi << "Error: can't read a file: '" << aPath.ToCString() << "'\n";
return 1;
}
/*const NCollection_Vector<MeshGroup>& aGroups = aLoader->Groups();
for (auto anIter = aGroups.cbegin(); anIter != aGroups.cend(); ++anIter)
{
const Quantity_Color& aDiffuseColor = anIter->Material.Aspect.DiffuseColor();
const Graphic3d_BSDF& aBSDF = anIter->Material.Aspect.BSDF();
std::cout << anIter->Material.Texture << std::endl;
std::cout << aDiffuseColor.Red() << ", " << aDiffuseColor.Green() << ", " << aDiffuseColor.Green() << std::endl;
std::cout << aBSDF.Kd.x() << ", " << aBSDF.Kd.y() << ", " << aBSDF.Kd.z() << std::endl << std::endl;
}*/
Handle(MeshScalarProperty) aProperty;
TCollection_AsciiString aSelEntry;
Handle(MeshVS_Mesh) aMesh = createMeshPresentation(aLoader, "", aSelEntry, aProperty);
ViewerTest::Display(aName, aMesh, Standard_False);
return 0;
}
#include <ObjDataWriter.h>
#include <AIS_ListOfInteractive.hxx>
// =============================================================================
// function : VSaveObj
// purpose :
// =============================================================================
static int VSaveObj (Draw_Interpretor& theDi,
Standard_Integer theArgNb,
const char** theArgVec)
{
if (theArgNb < 3)
{
theDi << theArgVec[0] << "Error: wrong number of arguments.\n";
return 1;
}
const TCollection_AsciiString aPath (theArgVec[1]);
AIS_ListOfInteractive aList;
Handle(ObjDataWriter) aWriter = new ObjDataWriter();
for (Standard_Integer anIter = 2; anIter < theArgNb; ++anIter)
{
TCollection_AsciiString aName (theArgVec[anIter]);
if (!GetMapOfAIS().IsBound2(aName))
{
theDi << aName << "is not exist.\n";
continue;
}
Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
if (anObject.IsNull())
{
theDi << aName << "is not an interactive object.\n";
continue;
}
/*Handle(MeshVS_Mesh) aMesh = Handle(MeshVS_Mesh)::DownCast(anObject);
if (!aMesh.IsNull())
{
aWriter->Write (aMesh->GetDataSource(), aPath, NULL);
}*/
aList.Append(anObject);
}
aWriter->Write (aList, aPath, NULL);
return 0;
}
//==============================================================================
//function : ViewerTest::Commands
//purpose : Add all the viewer command in the Draw_Interpretor
@@ -5556,6 +5725,14 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
"\n\t\t: -redisplay recomputes presentation of objects.",
__FILE__, VDisplay2, group);
theCommands.Add("vdisplayobj",
"vdisplayobj name path",
__FILE__, VDisplayObj, group);
theCommands.Add("vsaveobj",
"vsaveobj file names",
__FILE__, VSaveObj, group);
theCommands.Add ("vupdate",
"vupdate name1 [name2] ... [name n]"
"\n\t\t: Updates named objects in interactive context",
@@ -5757,10 +5934,6 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
"\n\t\t: Tests the animation of an object along a predefined trajectory.",
__FILE__,VPerf,group);
theCommands.Add("vanimation",
"vanimation CrankArmFile CylinderHeadFile PropellerFile EngineBlockFile",
__FILE__,VAnimation,group);
theCommands.Add("vsetshading",
"vsetshading : vsetshading name Quality(default=0.0008) "
"\n\t\t: Sets deflection coefficient that defines the quality of the shape representation in the shading mode.",

View File

@@ -15,13 +15,24 @@
#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
#include <windows.h>
#include <Aspect_Window.hxx>
#include <OpenGl_AVIWriter.hxx>
#include <V3d_View.hxx>
#endif
#include <ViewerTest.hxx>
#include <Aspect_Window.hxx>
#include <Draw.hxx>
#include <Draw_Interpretor.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressSentry.hxx>
#include <NCollection_Sequence.hxx>
#include <NCollection_DataMap.hxx>
#include <Image_PixMap.hxx>
#include <OSD_Timer.hxx>
#include <Precision.hxx>
#include <V3d_View.hxx>
#include <TCollection_AsciiString.hxx>
static Standard_Integer avi_record(Draw_Interpretor& /*di*/,
Standard_Integer argc, const char** argv)
@@ -84,14 +95,889 @@ static Standard_Integer avi_record(Draw_Interpretor& /*di*/,
return aResult;
}
extern "C"
{
#ifdef _MSC_VER
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "swscale.lib")
// suppress some common warnings in FFmpeg headers
#pragma warning(disable : 4244)
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#ifdef _MSC_VER
#pragma warning(default : 4244)
#endif
};
//! Video recording tool.
class ViewerTest_VideoRecorder : public Standard_Transient
{
public:
//! Empty constructor.
ViewerTest_VideoRecorder()
: myAVContext (NULL),
myVideoStream (NULL),
myVideoCodec (NULL),
myFrame (NULL),
myScaleCtx (NULL),
myPixFmtOut (AV_PIX_FMT_YUV420P),
myPixFmtSrc (AV_PIX_FMT_RGBA), // AV_PIX_FMT_BGR0
myFrameCount (0)
{
myFrameRate.num = 1;
myFrameRate.den = 30;
// initialize libavcodec, and register all codecs and formats, should be done once
av_register_all();
}
//! Destructor.
~ViewerTest_VideoRecorder()
{
Close();
}
//! Setup playback FPS. Should be set before Open().
void SetFramerate (const Standard_Integer theNumerator,
const Standard_Integer theDenominator)
{
myFrameRate.num = theNumerator;
myFrameRate.den = theDenominator;
}
//! Setup playback FPS. Should be set before Open().
//! For fixed-fps content, timebase should be 1/framerate and timestamp increments should be identical to 1.
void SetFramerate (const Standard_Integer theValue)
{
myFrameRate.num = int(theValue);
myFrameRate.den = 1;
}
//! Close the stream - stop recorder.
void Close()
{
if (myScaleCtx != NULL)
{
sws_freeContext (myScaleCtx);
}
if (myAVContext == NULL)
{
return;
}
// Write the trailer, if any. The trailer must be written before you close the CodecContexts open when you wrote the header;
// otherwise av_write_trailer() may try to use memory that was freed on av_codec_close().
av_write_trailer (myAVContext);
// close each codec
if (myVideoStream != NULL)
{
avcodec_close (myVideoStream->codec);
myVideoStream = NULL;
}
if (myFrame != NULL)
{
av_free (myPicDst.data[0]);
av_frame_free (&myFrame);
myFrame = NULL;
}
if (!(myAVContext->oformat->flags & AVFMT_NOFILE))
{
// close the output file
avio_close (myAVContext->pb);
}
// free the stream
avformat_free_context (myAVContext);
myAVContext = NULL;
}
//! Open output stream - start recorder.
Standard_Boolean Open (const char* theFileName,
const Standard_Integer theWidth,
const Standard_Integer theHeight)
{
Close();
myFrameCount = 0;
if (theWidth <= 0
|| theHeight <= 0)
{
return Standard_False;
}
// allocate the output media context
avformat_alloc_output_context2 (&myAVContext, NULL, NULL, theFileName);
if (myAVContext == NULL)
{
::Message::DefaultMessenger()->Send ("ViewerTest_VideoRecorder, could not deduce output format from file extension - using MPEG.", Message_Warning);
avformat_alloc_output_context2 (&myAVContext, NULL, "mpeg", theFileName);
}
if (myAVContext == NULL)
{
return Standard_False;
}
// add the audio stream using the default format codecs and initialize the codecs
if (!addVideoStream (myAVContext->oformat->video_codec, theWidth, theHeight))
{
Close();
return Standard_False;
}
// open video codec and allocate the necessary encode buffers
if (!openVideoCodec())
{
Close();
return Standard_False;
}
av_dump_format (myAVContext, 0, theFileName, 1); /// debug
// open the output file, if needed
if ((myAVContext->oformat->flags & AVFMT_NOFILE) == 0)
{
const int aResAv = avio_open (&myAVContext->pb, theFileName, AVIO_FLAG_WRITE);
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: could not open '") + theFileName + "', " + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
Close();
return Standard_False;
}
}
// write the stream header, if any
const int aResAv = avformat_write_header (myAVContext, NULL);
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not open output file '") + theFileName + "', " + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
Close();
return Standard_False;
}
return Standard_True;
}
//! Access RGBA frame, should NOT be re-initialized outside.
Image_PixMap& ChangeFrame()
{
return myImgSrcRgba;
}
//! Push new frame, should be called after Open().
Standard_Boolean PushFrame()
{
return writeVideoFrame (Standard_False);
}
protected:
//! Wrapper for av_strerror().
TCollection_AsciiString formatAvError (const int theError) const
{
char anErrBuf[AV_ERROR_MAX_STRING_SIZE] = {};
av_strerror (theError, anErrBuf, AV_ERROR_MAX_STRING_SIZE);
return anErrBuf;
}
//! Append video stream.
Standard_Boolean addVideoStream (const AVCodecID theCodecId,
const Standard_Integer theWidth,
const Standard_Integer theHeight)
{
// find the encoder
myVideoCodec = avcodec_find_encoder (theCodecId);
if (myVideoCodec == NULL)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not find encoder for ") + avcodec_get_name (theCodecId);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
myVideoStream = avformat_new_stream (myAVContext, myVideoCodec);
if (myVideoStream == NULL)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate stream!");
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
myVideoStream->id = myAVContext->nb_streams - 1;
AVCodecContext* aCodecCtx = myVideoStream->codec;
aCodecCtx->codec_id = theCodecId;
// resolution must be a multiple of two
aCodecCtx->width = theWidth;
aCodecCtx->height = theHeight;
// Timebase is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
// For fixed-fps content, timebase should be 1/framerate and timestamp increments should be identical to 1.
aCodecCtx->time_base.den = myFrameRate.num;
aCodecCtx->time_base.num = myFrameRate.den;
aCodecCtx->gop_size = 12; // emit one intra frame every twelve frames at most
aCodecCtx->pix_fmt = myPixFmtOut;
// some formats want stream headers to be separate
if (myAVContext->oformat->flags & AVFMT_GLOBALHEADER)
{
aCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
return Standard_True;
}
//! Open video codec.
Standard_Boolean openVideoCodec()
{
// open the codec
AVCodecContext* aCodecCtx = myVideoStream->codec;
AVDictionary* anOptions = NULL;
//av_dict_set (&anOptions, "threads", "auto", 0);
switch (aCodecCtx->codec_id)
{
case AV_CODEC_ID_MPEG2VIDEO:
{
// just for testing, we also add B frames
aCodecCtx->max_b_frames = 2;
aCodecCtx->bit_rate = 6000000;
break;
}
case AV_CODEC_ID_H264:
{
// use CRF (Constant Rate Factor) as best single-pass compressing method
av_dict_set (&anOptions, "crf", "20", 0); // quality 18-28, 23 is default (normal), 18 is almost lossless
av_dict_set (&anOptions, "preset", "slow", 0); // good compression (see also "veryslow", "ultrafast")
// live-capturing
//av_dict_set (&anOptions, "qp", "0", 0); // instead of crf
//av_dict_set (&anOptions, "preset", "ultrafast", 0);
// compatibility with devices
//av_dict_set (&anOptions, "profile", "baseline", 0);
//av_dict_set (&anOptions, "level", "3.0", 0);
break;
}
/*case AV_CODEC_ID_VP8:
case AV_CODEC_ID_VP9:
{
av_dict_set (&anOptions, "crf", "20", 0); // quality 4<>63, 10 is normal
break;
}*/
}
int aResAv = avcodec_open2 (aCodecCtx, myVideoCodec, &anOptions);
if (anOptions != NULL)
{
av_dict_free (&anOptions);
}
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not open video codec, ") + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
// allocate and init a re-usable frame
myFrame = av_frame_alloc();
if (myFrame == NULL)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate video frame!");
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
// allocate the encoded raw picture
aResAv = avpicture_alloc (&myPicDst, aCodecCtx->pix_fmt, aCodecCtx->width, aCodecCtx->height);
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate picture ")
+ aCodecCtx->width+ "x" + aCodecCtx->height + ", " + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
// copy data and linesize picture pointers to frame
myFrame->format = aCodecCtx->pix_fmt;
myFrame->width = aCodecCtx->width;
myFrame->height = aCodecCtx->height;
*((AVPicture* )myFrame) = myPicDst;
const Standard_Size aStride = aCodecCtx->width + 16 - (aCodecCtx->width % 16);
if (!myImgSrcRgba.InitZero (Image_PixMap::ImgRGBA, aCodecCtx->width, aCodecCtx->height, aStride))
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate RGBA32 picture ")
+ aCodecCtx->width+ "x" + aCodecCtx->height;
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
myImgSrcRgba.SetTopDown(true);
myScaleCtx = sws_getContext (aCodecCtx->width, aCodecCtx->height, myPixFmtSrc,
aCodecCtx->width, aCodecCtx->height, aCodecCtx->pix_fmt,
SWS_BICUBIC, NULL, NULL, NULL);
if (myScaleCtx == NULL)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not initialize the conversion context!");
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
return Standard_True;
}
//! Write new video frame.
Standard_Boolean writeVideoFrame (const Standard_Boolean theToFlush)
{
int aResAv = 0;
AVCodecContext* aCodecCtx = myVideoStream->codec;
if (!theToFlush)
{
uint8_t* aSrcData[4] = { (uint8_t*)myImgSrcRgba.ChangeData(), NULL, NULL, NULL };
int aSrcLinesize[4] = { (int )myImgSrcRgba.SizeRowBytes(), 0, 0, 0 };
sws_scale (myScaleCtx,
aSrcData, aSrcLinesize,
0, aCodecCtx->height,
myPicDst.data, myPicDst.linesize);
}
AVPacket aPacket = { 0 };
av_init_packet (&aPacket);
if ((myAVContext->oformat->flags & AVFMT_RAWPICTURE) != 0
&& !theToFlush)
{
// raw video case - directly store the picture in the packet
aPacket.flags |= AV_PKT_FLAG_KEY;
aPacket.stream_index = myVideoStream->index;
aPacket.data = myPicDst.data[0];
aPacket.size = sizeof(AVPicture);
aResAv = av_interleaved_write_frame (myAVContext, &aPacket);
}
else
{
// encode the image
myFrame->pts = myFrameCount;
int isGotPacket = 0;
aResAv = avcodec_encode_video2 (aCodecCtx, &aPacket, theToFlush ? NULL : myFrame, &isGotPacket);
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not encode video frame, ") + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
// if size is zero, it means the image was buffered
if (isGotPacket)
{
const AVRational& aTimeBase = aCodecCtx->time_base;
// rescale output packet timestamp values from codec to stream timebase
aPacket.pts = av_rescale_q_rnd (aPacket.pts, aTimeBase, myVideoStream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
aPacket.dts = av_rescale_q_rnd (aPacket.dts, aTimeBase, myVideoStream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
aPacket.duration = av_rescale_q (aPacket.duration, aTimeBase, myVideoStream->time_base);
aPacket.stream_index = myVideoStream->index;
// write the compressed frame to the media file
aResAv = av_interleaved_write_frame (myAVContext, &aPacket);
}
else
{
aResAv = 0;
}
}
if (aResAv < 0)
{
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not write video frame, ") + formatAvError (aResAv);
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
return Standard_False;
}
++myFrameCount;
return Standard_True;
}
protected:
AVFormatContext* myAVContext;
AVStream* myVideoStream;
AVCodec* myVideoCodec;
AVFrame* myFrame;
AVPicture myPicDst;
SwsContext* myScaleCtx;
AVRational myFrameRate;
AVPixelFormat myPixFmtOut;
Image_PixMap myImgSrcRgba;
AVPixelFormat myPixFmtSrc;
int64_t myFrameCount;
public:
DEFINE_STANDARD_RTTIEXT(ViewerTest_VideoRecorder, Standard_Transient) // Type definition
};
//DEFINE_STANDARD_HANDLE(ViewerTest_VideoRecorder, Standard_Transient)
//IMPLEMENT_STANDARD_HANDLE (ViewerTest_VideoRecorder, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_VideoRecorder, Standard_Transient)
//DEFINE_STANDARD_HANDLE(ViewerTest_Animation, Standard_Transient)
//! Structure defining animation sequence
class ViewerTest_Animation : public Standard_Transient
{
public:
//! Connected animation slice
struct Slice
{
Standard_Real StartTime; //!< presentation timestamp within parent animation slice
Standard_Real Duration; //!< animation duration
Handle(ViewerTest_Animation) Animation; //!< connected animation to be executed
Slice() : StartTime (0.0), Duration (0.0) {}
};
public:
TCollection_AsciiString OnStart; //!< procedure to be evaluated at the beggining of this animation slice
TCollection_AsciiString OnEnd; //!< procedure to be evaluated at the end of this animation slice
TCollection_AsciiString OnRedraw; //!< procedure to be evaluated at every frame during this animation slice
NCollection_Sequence<Slice> Slices; //!< sequence of child animation slices
public:
//! Empty constructor
ViewerTest_Animation() {}
//! Reset the animation definition
void Reset()
{
OnStart.Clear();
OnEnd.Clear();
OnRedraw.Clear();
Slices.Clear();
}
//! Estimated duration
Standard_Real Duration() const
{
Standard_Real aDuration = -1.0;
for (NCollection_Sequence<Slice>::Iterator aSliceIter (Slices);
aSliceIter.More(); aSliceIter.Next())
{
Standard_Real aSliceDuration = aSliceIter.Value().Duration >= 0.0
? aSliceIter.Value().Duration
: aSliceIter.Value().Animation->Duration();
aDuration = Max (aDuration, aSliceIter.Value().StartTime + aSliceDuration);
}
return aDuration;
}
public:
DEFINE_STANDARD_RTTIEXT(ViewerTest_Animation,Standard_Transient) // Type definition
};
//IMPLEMENT_STANDARD_HANDLE (ViewerTest_Animation, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_Animation, Standard_Transient)
static NCollection_DataMap<TCollection_AsciiString, Handle(ViewerTest_Animation)> ViewerTest_TheAnimationsMap;
//! Evaluate animation sequence
static void VEvalAnimation (Draw_Interpretor& theDI,
const ViewerTest_Animation& theAnim,
const Standard_Real theStartPts,
const Standard_Real theEndPts,
const Standard_Real thePrevPts,
const Standard_Real thePts)
{
const Standard_Real aLocPts = thePts - theStartPts;
if ( thePts >= theStartPts
&& thePrevPts < theStartPts
&& !theAnim.OnStart.IsEmpty())
{
const TCollection_AsciiString aCmd = theAnim.OnStart + " " + thePts + " " + aLocPts + " onStart";
theDI.Eval (aCmd.ToCString());
}
for (NCollection_Sequence<ViewerTest_Animation::Slice>::Iterator aSliceIter (theAnim.Slices);
aSliceIter.More(); aSliceIter.Next())
{
VEvalAnimation (theDI,
*aSliceIter.Value().Animation,
aSliceIter.Value().StartTime,
aSliceIter.Value().StartTime + aSliceIter.Value().Duration,
thePrevPts,
thePts);
}
if (!theAnim.OnRedraw.IsEmpty()
&& thePts >= theStartPts
&& thePts < theEndPts)
{
const TCollection_AsciiString aCmd = theAnim.OnRedraw + " " + thePts + " " + aLocPts + " onRedraw";
theDI.Eval (aCmd.ToCString());
}
if ( thePts >= theEndPts
&& thePrevPts < theEndPts
&& !theAnim.OnEnd.IsEmpty())
{
const TCollection_AsciiString aCmd = theAnim.OnEnd + " " + thePts + " " + aLocPts + " onEnd";
theDI.Eval (aCmd.ToCString());
}
}
//==============================================================================
//function : VAnimation
//purpose :
//==============================================================================
static Standard_Integer VAnimation (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
const char** theArgVec)
{
Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
if (theArgNb < 2)
{
for (NCollection_DataMap<TCollection_AsciiString, Handle(ViewerTest_Animation)>::Iterator anAnimIter (ViewerTest_TheAnimationsMap);
anAnimIter.More(); anAnimIter.Next())
{
theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
}
return 0;
}
Standard_Boolean toPlay = Standard_False;
Standard_Boolean isInteractive = Standard_False;
Standard_Real aPlayFrom = 0.0;
Standard_Real aPlayDuration = -1.0;
Standard_Integer aPlayFpsNum = 0;
Standard_Integer aPlayFpsDen = 1;
Standard_CString aRecordFile = NULL;
Standard_Integer aRecWidth = 0;
Standard_Integer aRecHeight = 0;
TCollection_AsciiString aName;
Handle(ViewerTest_Animation) anAnim;
Standard_Integer anArgIter = 1;
for (; anArgIter < theArgNb; ++anArgIter)
{
Standard_CString anArg = theArgVec[anArgIter];
TCollection_AsciiString anArgCase (anArg);
anArgCase.LowerCase();
if (anArgCase == "-onstart")
{
if (++anArgIter >= theArgNb
|| anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
anAnim->OnStart = theArgVec[anArgIter];
}
else if (anArgCase == "-onend")
{
if (++anArgIter >= theArgNb
|| anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
anAnim->OnEnd = theArgVec[anArgIter];
}
else if (anArgCase == "-onredraw"
|| anArgCase == "-ondraw")
{
if (++anArgIter >= theArgNb
|| anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
anAnim->OnRedraw = theArgVec[anArgIter];
}
else if (anArgCase == "-reset")
{
if (anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
anAnim->Reset();
}
else if (anArgCase == "-delete")
{
if (++anArgIter < theArgNb
|| anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
ViewerTest_TheAnimationsMap.UnBind (aName);
}
else if (anArgCase == "-addslice"
|| anArgCase == "-slice")
{
if (anArgIter + 3 >= theArgNb
|| anAnim.IsNull())
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
ViewerTest_Animation::Slice aSlice;
aSlice.StartTime = Draw::Atof (theArgVec[++anArgIter]);
aSlice.Duration = Draw::Atof (theArgVec[++anArgIter]);
if (aSlice.StartTime < 0.0)
{
std::cout << "Error: PTS should not be negative (specified " << aSlice.StartTime << ")\n";
return 1;
}
TCollection_AsciiString anOtherName (theArgVec[++anArgIter]);
if (!ViewerTest_TheAnimationsMap.Find (anOtherName, aSlice.Animation))
{
std::cout << "Error: animation with name '" << anOtherName << "' is not registered!\n";
return 1;
}
Standard_Integer anIndex = 1;
for (NCollection_Sequence<ViewerTest_Animation::Slice>::Iterator aSliceIter (anAnim->Slices);
aSliceIter.More(); aSliceIter.Next(), ++anIndex)
{
if (aSlice.StartTime < aSliceIter.Value().StartTime)
{
anAnim->Slices.InsertBefore (anIndex, aSlice);
anIndex = -1;
break;
}
}
if (anIndex != -1)
{
anAnim->Slices.Append (aSlice);
}
}
else if (anArgCase == "-play")
{
toPlay = Standard_True;
}
else if (anArgCase == "-playfrom")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
aPlayFrom = Draw::Atof (theArgVec[anArgIter]);
}
else if (anArgCase == "-playduration"
|| anArgCase == "-playdur")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
}
else if (anArgCase == "-playfps"
|| anArgCase == "-fps")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
TCollection_AsciiString aFpsStr (theArgVec[anArgIter]);
Standard_Integer aSplitIndex = aFpsStr.FirstLocationInSet ("/", 1, aFpsStr.Length());
if (aSplitIndex == 0)
{
aPlayFpsNum = aFpsStr.IntegerValue();
aPlayFpsDen = 1;
}
else
{
const TCollection_AsciiString aDenStr = aFpsStr.Split (aSplitIndex);
aFpsStr.Split (aFpsStr.Length() - 1);
const TCollection_AsciiString aNumStr = aFpsStr;
aPlayFpsNum = aNumStr.IntegerValue();
aPlayFpsDen = aDenStr.IntegerValue();
if (aPlayFpsDen < 1)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
}
}
else if (anArgCase == "-inter"
|| anArgCase == "-interactive")
{
isInteractive = Standard_True;
}
else if (anArgCase == "-rec"
|| anArgCase == "-record")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
aRecordFile = theArgVec[anArgIter];
}
else if (anArgCase == "-recwidth"
|| anArgCase == "-recordwidth")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
aRecWidth = Draw::Atoi (theArgVec[anArgIter]);
}
else if (anArgCase == "-recheight"
|| anArgCase == "-recordheight")
{
if (++anArgIter >= theArgNb)
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
aRecHeight = Draw::Atoi (theArgVec[anArgIter]);
}
else if (aName.IsEmpty())
{
aName = anArg;
if (!ViewerTest_TheAnimationsMap.Find (aName, anAnim))
{
anAnim = new ViewerTest_Animation();
ViewerTest_TheAnimationsMap.Bind (aName, anAnim);
}
}
else
{
std::cout << "Error: wrong syntax at '" << anArg << "'\n";
return 1;
}
}
if (!toPlay)
{
return 0;
}
// play animation
if (aPlayDuration < 0.0)
{
aPlayDuration = anAnim->Duration();
}
Standard_Real aPtsTo = aPlayFrom + aPlayDuration;
OSD_Timer aTimer;
aTimer.Start();
Standard_Real aPrevPts = aPlayFrom - Precision::Confusion();
if (aPlayFpsNum > 0)
{
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
Handle(ViewerTest_VideoRecorder) aRecorder;
if (aRecordFile != NULL)
{
if (aView.IsNull())
{
std::cout << "Error: no active view!\n";
return 1;
}
Standard_Integer aWinWidth = 0, aWinHeight = 0;
aView->Window()->Size (aWinWidth, aWinHeight);
if (aRecWidth <= 0)
{
aRecWidth = aWinWidth;
}
if (aRecHeight <= 0)
{
aRecHeight = aWinHeight;
}
aRecorder = new ViewerTest_VideoRecorder();
aRecorder->SetFramerate (aPlayFpsNum, aPlayFpsDen);
if (!aRecorder->Open (aRecordFile, aRecWidth, aRecHeight))
{
return 0;
}
}
// fixed FPS, bad formula - to be corrected
const Standard_Real aFrameDur = Standard_Real(aPlayFpsDen) / Standard_Real(aPlayFpsNum);
for (Standard_Real aPts = aPlayFrom; aPts <= aPtsTo; aPts += aFrameDur)
{
VEvalAnimation (theDI, *anAnim,
aPlayFrom, aPtsTo,
aPrevPts, aPts);
aPrevPts = aPts;
if (!aRecorder.IsNull())
{
if (!aView->ToPixMap (aRecorder->ChangeFrame(),
aRecorder->ChangeFrame().SizeX(), aRecorder->ChangeFrame().SizeY(),
Graphic3d_BT_RGBA, Standard_True, V3d_SDO_MONO))
{
std::cout << "Error: view dump is failed!\n";
return 0;
}
if (!aRecorder->PushFrame())
{
return 0;
}
}
if (isInteractive)
{
// handle user events
theDI.Eval ("after 1 set waiter 1");
theDI.Eval ("vwait waiter");
}
}
}
else
{
// live playback
for (Standard_Real aPts = aPlayFrom; aPts <= aPtsTo; aPts = aTimer.ElapsedTime())
{
VEvalAnimation (theDI, *anAnim,
aPlayFrom, aPtsTo,
aPrevPts, aPts);
aPrevPts = aPts;
if (isInteractive)
{
// handle user events
theDI.Eval ("after 1 set waiter 1");
theDI.Eval ("vwait waiter");
}
}
}
aTimer.Show();
//theDI << "Duration: " << aTimer.ElapsedTime() << " sec.\n";
return 0;
}
//=======================================================================
//function : AviCommands
//purpose :
//purpose :
//=======================================================================
void ViewerTest::AviCommands(Draw_Interpretor& theCommands)
{
const char* group = "ViewerTest AVI commands";
const char* aGroup = "ViewerTest AVI commands";
theCommands.Add("vrecord", "vrecord [option]\n"
"where [option] can be:\n"
@@ -102,5 +988,51 @@ void ViewerTest::AviCommands(Draw_Interpretor& theCommands)
"\tstatus : log error message,\n"
"\tsave : close the AVI file\n",
__FILE__,
&avi_record, group); //Draft_Modification
&avi_record, aGroup); //Draft_Modification
theCommands.Add("vanimation", "Alias for vanimation",
__FILE__, VAnimation, aGroup);
theCommands.Add("vanim",
"List existing animations:"
"\n\t\t: vanim"
"\n\t\t: Animation playback:"
"\n\t\t: vanim -play AnimName [-interactive] [-fps FPS=0/1]"
"\n\t\t: [-playFrom Sec=0] [-playDuration Sec=-1.0]"
"\n\t\t: [-record VideoFileName]"
"\n\t\t: [-recordWidth Width] [-recordHeight Height]"
"\n\t\t: where"
"\n\t\t: -interactive handle user events on idle"
"\n\t\t: -playFrom animation start PTS"
"\n\t\t: -playDuration animation duration"
"\n\t\t: -playFps constant framerate for recording (e.g. 30/1),"
"\n\t\t: disables live time"
"\n\t\t: -record record to the file"
"\n\t\t: -recordWidth width of recorded video"
"\n\t\t: (window width if not set)"
"\n\t\t: -recordHeight height of recorded video"
"\n\t\t: (window height if not set)"
"\n\t\t: Animation definition:"
"\n\t\t: vanim AnimName"
"\n\t\t: -delete"
"\n\t\t: -onStart StartProcName"
"\n\t\t: -onEnd EndProcName"
"\n\t\t: -onRedraw AnimProcName"
"\n\t\t: -addSlice FromPts Duration OtherAnimName"
"\n\t\t: -reset"
"\n\t\t: where"
"\n\t\t: -delete remove animation with specified name"
"\n\t\t: -onStart procedure to be called once"
"\n\t\t: at the beginning"
"\n\t\t: -onEnd procedure to be called once at the end"
"\n\t\t: -onRedraw procedure to be called at each frame"
"\n\t\t: -addSlice call another animation within specified duration"
"\n\t\t: -reset clear list of linked slices"
"\n\t\t: Callback procedure should has the following prototype:"
"\n\t\t: callback thePts theLocalPts theEvent"
"\n\t\t: where"
"\n\t\t: -thePts current presentation timestamp"
"\n\t\t: -theLocalPts presentation timestamp within slice"
"\n\t\t: -theEvent event from the list onStart,onEnd,onRedraw",
__FILE__, VAnimation, aGroup);
}

View File

@@ -6295,6 +6295,143 @@ static int VPriority (Draw_Interpretor& theDI,
return 0;
}
#include <MeshVS_Mesh.hxx>
#include <MeshVS_DataSource.hxx>
#include <MeshPresentation.h>
// ======================================================================
// function : VUpdateVertices
// purpose :
// ======================================================================
static Standard_Integer VUpdateVertices (Draw_Interpretor& theDI,
Standard_Integer theArgNum,
const char** theArgs)
{
if (theArgNum < 3)
{
return 1;
}
const TCollection_AsciiString aShapeName (theArgs[1]);
const TCollection_AsciiString aNewShapeName (theArgs[2]);
Standard_Real a = 1.0;
Standard_Real k = 1.0;
Standard_Real f = 1.0;
for (Standard_Integer anIter = 3; anIter < theArgNum; ++anIter)
{
TCollection_AsciiString aValue(theArgs[anIter]);
aValue.LowerCase();
if (aValue == "-a")
{
if (++anIter >= theArgNum)
{
theDI << "Syntax error.\n";
return 1;
}
a = Draw::Atof(theArgs[anIter]);
}
if (aValue == "-k")
{
if (++anIter >= theArgNum)
{
theDI << "Syntax error.\n";
return 1;
}
k = Draw::Atof(theArgs[anIter]);
}
if (aValue == "-f")
{
if (++anIter >= theArgNum)
{
theDI << "Syntax error.\n";
return 1;
}
f = Draw::Atof(theArgs[anIter]);
}
}
TopoDS_Shape aShape = DBRep::Get (theArgs[1]);
if (aShape.IsNull())
{
theDI << "Error: This shape '" << aShapeName << "' is not exist.\n";
return 1;
}
TopLoc_Location aLocation;
TopExp_Explorer anExplorer;
BRep_Builder aBuilder;
TopoDS_Compound aNewShape;
aBuilder.MakeCompound(aNewShape);
for (anExplorer.Init (aShape, TopAbs_FACE); anExplorer.More(); anExplorer.Next())
{
TopoDS_Shape aCurrent = anExplorer.Current();
TopoDS_Face& aFace = TopoDS::Face (aCurrent);
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation);
TColgp_Array1OfPnt& aNodes = aTriangulation->ChangeNodes();
for (Standard_Integer anIter = aNodes.Lower(); anIter <= aNodes.Upper(); ++anIter)
{
const Standard_Real aCurrentZ = aNodes.Value(anIter).Coord().Z();
const Standard_Real anAdd = a * sin(k * aNodes.Value(anIter).Coord().Y() + f);
aNodes.ChangeValue(anIter).ChangeCoord().SetZ (aCurrentZ + anAdd);
}
if (!aTriangulation->HasNormals())
{
Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal(0, 3 * aTriangulation->NbNodes() - 1);
aTriangulation->SetNormals(aNormals);
}
if (aTriangulation->HasNormals())
{
TShort_Array1OfShortReal& aNormals = aTriangulation->ChangeNormals();
Standard_ShortReal* aNormArr = &(aNormals.ChangeValue (aNormals.Lower()));
const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
for (Standard_Integer anIter = aTriangles.Lower(); anIter <= aTriangles.Upper(); ++anIter)
{
Standard_Integer indices[3];
aTriangles.Value (anIter).Get (indices[0], indices[1], indices[2]);
const gp_Pnt& aVertex1 = aNodes.Value (indices[0]);
const gp_Pnt& aVertex2 = aNodes.Value (indices[1]);
const gp_Pnt& aVertex3 = aNodes.Value (indices[2]);
const gp_Dir aDir1 (aVertex2.XYZ() - aVertex1.XYZ());
const gp_Dir aDir2 (aVertex3.XYZ() - aVertex1.XYZ());
const gp_Dir aNormal = aDir1.Crossed(aDir2);
for (int i = 0; i < 3; ++i)
{
const Standard_Integer anId = 3 * (indices[i] - aNodes.Lower());
aNormArr[anId + 0] = aNormal.X();
aNormArr[anId + 1] = aNormal.Y();
aNormArr[anId + 2] = aNormal.Z();
}
}
}
aBuilder.Add (aNewShape, aCurrent);
}
DBRep::Set (aNewShapeName.ToCString(), aNewShape);
TCollection_AsciiString aScript ("vdisplay "); aScript += aNewShapeName;
theDI.Eval (aScript.ToCString());
return 0;
}
//=======================================================================
//function : ObjectsCommands
//purpose :
@@ -6602,4 +6739,8 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
"vpriority [-noupdate|-update] name [value]\n\t\t prints or sets the display priority for an object",
__FILE__,
VPriority, group);
theCommands.Add("vupdatevertices",
"vupdatevertices shapeName newShapeName [-a value] [-k value] [-f value]",
__FILE__, VUpdateVertices, group);
}

View File

@@ -4473,21 +4473,7 @@ static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** ar
}
else if (argc < 2)
{
di << "Use: vzlayer ";
di << " add/del/get/settings/enable/disable [id]\n";
di << " add - add new z layer to viewer and print its id\n";
di << " del - del z layer by its id\n";
di << " get - print sequence of z layers in increasing order of their overlay level\n";
di << " settings - print status of z layer settings\n";
di << " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n enables given setting for the z layer\n";
di << " enable (p[ositive]offset/n[egative]offset) \n enables given setting for the z layer\n";
di << " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n disables given setting for the z layer\n";
di << "\nWhere id is the layer identificator\n";
di << "\nExamples:\n";
di << " vzlayer add\n";
di << " vzlayer enable poffset 1\n";
di << " vzlayer disable depthtest 1\n";
di << " vzlayer del 1\n";
di << di.PrintHelp (argv[0]);
return 1;
}
@@ -4625,6 +4611,10 @@ static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** ar
{
aSettings.SetDepthOffsetNegative();
}
else if (aSubOp == "textureenv")
{
aSettings.UseEnvironmentTexture = true;
}
aViewer->SetZLayerSettings (anId, aSettings);
}
@@ -4662,6 +4652,10 @@ static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** ar
{
aSettings.DisableSetting (Graphic3d_ZLayerDepthOffset);
}
else if (aSubOp == "textureenv")
{
aSettings.UseEnvironmentTexture = false;
}
aViewer->SetZLayerSettings (anId, aSettings);
}
@@ -6572,11 +6566,9 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb,
);
}
aView->SetTextureEnv(aTexEnv);
aView->SetSurfaceDetail(V3d_TEX_ENVIRONMENT);
}
else // Disabling environment mapping
{
aView->SetSurfaceDetail(V3d_TEX_NONE);
Handle(Graphic3d_TextureEnv) aTexture;
aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
}
@@ -6980,40 +6972,6 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
return 1;
}
//===============================================================================================
//function : VSetTextureMode
//purpose :
//===============================================================================================
static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
{
if (theArgsNb < 3)
{
theDi << theArgVec[0] << ": insufficient command arguments. Type help for more information.\n";
return 1;
}
TCollection_AsciiString aViewName (theArgVec[1]);
if (!ViewerTest_myViews.IsBound1 (aViewName))
{
theDi << theArgVec[0] << ": view is not found.\n";
return 1;
}
const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
switch (atoi (theArgVec[2]))
{
case 0: aView->SetSurfaceDetail (V3d_TEX_NONE); break;
case 1: aView->SetSurfaceDetail (V3d_TEX_ENVIRONMENT); break;
case 2: aView->SetSurfaceDetail (V3d_TEX_ALL); break;
default:
theDi << theArgVec[0] << ": invalid mode.\n";
return 1;
}
aView->Redraw();
return 0;
}
//===============================================================================================
//function : VZRange
//purpose :
@@ -8301,6 +8259,8 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
theDI << "samples: " << aParams.SamplesPerPixel << "\n";
theDI << "filtering: " << (aParams.IsGIFilteringEnabled ? "on" : "off") << "\n";
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
theDI << "shadingModel: ";
switch (aView->ShadingModel())
@@ -8424,6 +8384,48 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
aParams.RaytracingDepth = aDepth;
}
}
else if (aFlag == "-maxrad"
|| aFlag == "-rclamp")
{
if (toPrint)
{
theDI << aParams.RadianceClampValue << " ";
continue;
}
else if (++anArgIter >= theArgNb)
{
std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
return 1;
}
aParams.RadianceClampValue = Draw::Atoi (theArgVec[anArgIter]);
}
else if (aFlag == "-samples"
|| aFlag == "-spp")
{
if (toPrint)
{
theDI << aParams.SamplesPerPixel << " ";
continue;
}
else if (++anArgIter >= theArgNb)
{
std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
return 1;
}
const Standard_Integer aSamples = Draw::Atoi (theArgVec[anArgIter]);
if (aSamples < 0)
{
std::cerr << "Error: invalid ray-tracing samples per pixel " << aSamples << ". SPP should be a positive number.\n";
return 1;
}
else
{
aParams.SamplesPerPixel = aSamples;
}
}
else if (aFlag == "-shad"
|| aFlag == "-shadows")
{
@@ -8510,6 +8512,22 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
}
}
else if (aFlag == "-filter" || aFlag == "-pp" )
{
if (toPrint)
{
theDI << (aParams.IsGIFilteringEnabled ? "on" : "off") << " ";
continue;
}
Standard_Boolean toEnable = Standard_True;
if (++anArgIter < theArgNb
&& !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
{
--anArgIter;
}
aParams.IsGIFilteringEnabled = toEnable;
}
else if (aFlag == "-blockedrng"
|| aFlag == "-brng")
{
@@ -8828,6 +8846,69 @@ static Standard_Integer VXRotate (Draw_Interpretor& di,
return 0;
}
static Standard_Integer VShiftCam (Draw_Interpretor& theDi,
Standard_Integer theArgNb,
const char** theArgVec)
{
Handle(V3d_View) anAISView = ViewerTest::CurrentView();
if (anAISView.IsNull())
{
std::cout << theArgVec[0] << ": please initialize or activate view.\n";
return 1;
}
Standard_Real anAtX = 0.0;
Standard_Real anAtY = 0.0;
Standard_Real anAtZ = 0.0;
anAISView->At(anAtX, anAtY, anAtZ);
Standard_Real anEyeX = 0.0;
Standard_Real anEyeY = 0.0;
Standard_Real anEyeZ = 0.0;
anAISView->Eye(anEyeX, anEyeY, anEyeZ);
Graphic3d_Vec3 aDeltaVec(anAtX - anEyeX, anAtY - anEyeY, anAtZ - anEyeZ);
Standard_Real aDelta = Draw::Atof (theArgVec[1]);
anAISView->SetEye (anEyeX + aDeltaVec.x() * aDelta,
anEyeY + aDeltaVec.y() * aDelta,
anEyeZ + aDeltaVec.z() * aDelta);
anAISView->SetAt (anAtX + aDeltaVec.x() * aDelta,
anAtY + aDeltaVec.y() * aDelta,
anAtZ + aDeltaVec.z() * aDelta);
return 0;
}
static Standard_Integer VCamChangeAt (Draw_Interpretor& theDI,
Standard_Integer theArgNb,
const char** theArgVec)
{
Handle(V3d_View) anAISView = ViewerTest::CurrentView();
if (anAISView.IsNull())
{
std::cout << theArgVec[0] << ": please initialize or activate view.\n";
return 1;
}
Standard_Real anAtX = 0.0;
Standard_Real anAtY = 0.0;
Standard_Real anAtZ = 0.0;
anAISView->At(anAtX, anAtY, anAtZ);
Standard_Real anEyeX = 0.0;
Standard_Real anEyeY = 0.0;
Standard_Real anEyeZ = 0.0;
anAISView->Eye(anEyeX, anEyeY, anEyeZ);
Graphic3d_Vec3 aDeltaVec (anAtX - anEyeX, anAtY - anEyeY, anAtZ - anEyeZ);
Standard_Real aDelta = Draw::Atof (theArgVec[1]);
anAISView->SetAt (anAtX + aDeltaVec.x() * aDelta,
anAtY + aDeltaVec.y() * aDelta,
anAtZ + aDeltaVec.z() * aDelta);
return 0;
}
//=======================================================================
//function : ViewerCommands
//purpose :
@@ -9023,7 +9104,9 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
" settings - print status of z layer settings\n"
" enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n enables given setting for the z layer\n"
" enable (p[ositive]offset/n[egative]offset) \n enables given setting for the z layer\n"
" enable textureenv \n enables environment texture mapping\n"
" disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n disables given setting for the z layer\n"
" disable textureenv \n disables environment texture mapping\n"
"\nWhere id is the layer identificator\n"
"\nExamples:\n"
" vzlayer add\n"
@@ -9278,13 +9361,6 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
" change <plane_name> capping hatch on/off/<id> - set hatching mask.\n"
" please use VSetTextureMode command to enable texture rendering in view.\n"
, __FILE__, VClipPlane, group);
theCommands.Add("vsettexturemode", "vsettexturemode view_name mode \n"
" mode can be:\n"
" 0 - no textures enabled in view.\n"
" 1 - only environment textures enabled.\n"
" 2 - all textures enabled.\n"
" this command sets texture details mode for the specified view.\n"
, __FILE__, VSetTextureMode, group);
theCommands.Add("vdefaults",
"vdefaults [-absDefl value]"
"\n\t\t: [-devCoeff value]"
@@ -9360,4 +9436,12 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"vprogressive",
__FILE__, VProgressiveMode, group);
#endif
theCommands.Add("vshiftcam",
"vshiftcam delta",
__FILE__, VShiftCam, group);
theCommands.Add("vcamchangeat",
"vcamchangeat delta",
__FILE__, VCamChangeAt, group);
}

View File

@@ -839,11 +839,6 @@ static Standard_Integer meshcolors( Draw_Interpretor& di,
aBuilder->SetInvalidColor(Quantity_NOC_BLACK);
aBuilder->SetTextureCoords(aScaleMap);
aMesh->AddBuilder(aBuilder, Standard_True);
//set viewer to display texures
const Handle(V3d_Viewer)& aViewer = anIC->CurrentViewer();
for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
aViewer->ActiveView()->SetSurfaceDetail(V3d_TEX_ALL);
}
aMesh->GetDrawer()->SetBoolean ( MeshVS_DA_ColorReflection, Standard_Boolean(aReflection) );

36
tests/bugs/vis/bug26434 Normal file
View File

@@ -0,0 +1,36 @@
puts "============"
puts "CR26434"
puts "============"
puts ""
##########################################################################################
puts "Visualization - Textured objects should have priority over the environment mapping"
##########################################################################################
pload MODELING VISUALIZATION
vclear
vclose all
vinit View1
vsetdispmode 1
box b0 -1 -1 -1 1 2 3
box b1 1 1 1 1 2 3
vdisplay b0 b1
vzbufftrihedron
vfit
vdump $imagedir/${casename}_0.png
vtexture b1 0
vdump $imagedir/${casename}_1.png
puts "Checking that texture have priority over the environment mapping"
vtextureenv on 0
vdump $imagedir/${casename}_2.png