Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
iMSTK
iMSTK
Commits
614e296e
Commit
614e296e
authored
May 16, 2021
by
Andrew Wilson
🐘
Browse files
ENH: RenderDelegate to render face normals from windings
parent
f3fa0d62
Changes
8
Hide whitespace changes
Inline
Side-by-side
Examples/TaskGraph/Configuration/taskGraphConfigureExample.cpp
View file @
614e296e
...
...
@@ -112,17 +112,21 @@ makeClothObj(const std::string& name, double width, double height, int nRows, in
pbdModel
->
setModelGeometry
(
clothMesh
);
pbdModel
->
configure
(
pbdParams
);
// Setup the VisualModel
imstkNew
<
RenderMaterial
>
material
;
material
->
setBackFaceCulling
(
false
);
material
->
setColor
(
Color
::
LightGray
);
material
->
setDisplayMode
(
RenderMaterial
::
DisplayMode
::
WireframeSurface
);
auto
clothVisualModel
=
std
::
make_shared
<
VisualModel
>
(
clothMesh
);
clothVisualModel
->
setRenderMaterial
(
material
);
// Setup visual models
imstkNew
<
VisualModel
>
clothModel
;
clothModel
->
setGeometry
(
clothMesh
);
clothModel
->
getRenderMaterial
()
->
setBackFaceCulling
(
false
);
clothModel
->
getRenderMaterial
()
->
setColor
(
Color
::
LightGray
);
clothModel
->
getRenderMaterial
()
->
setDisplayMode
(
RenderMaterial
::
DisplayMode
::
WireframeSurface
);
imstkNew
<
VisualModel
>
clothSurfaceNormals
;
clothSurfaceNormals
->
setGeometry
(
clothMesh
);
clothSurfaceNormals
->
getRenderMaterial
()
->
setDisplayMode
(
RenderMaterial
::
DisplayMode
::
SurfaceNormals
);
clothSurfaceNormals
->
getRenderMaterial
()
->
setPointSize
(
0.5
);
// Setup the Object
clothObj
->
addVisualModel
(
clothVisualModel
);
clothObj
->
addVisualModel
(
clothModel
);
clothObj
->
addVisualModel
(
clothSurfaceNormals
);
clothObj
->
setPhysicsGeometry
(
clothMesh
);
clothObj
->
setDynamicalModel
(
pbdModel
);
...
...
Source/Rendering/CMakeLists.txt
View file @
614e296e
...
...
@@ -13,6 +13,7 @@ set(VTK_H_FILES
VTKRenderer/RenderDelegate/imstkVTKImageDataRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKSurfaceMeshRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKSurfaceNormalRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKTetrahedralMeshRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKHexahedralMeshRenderDelegate.h
VTKRenderer/RenderDelegate/imstkVTKCylinderRenderDelegate.h
...
...
@@ -34,6 +35,7 @@ set(VTK_CPP_FILES
VTKRenderer/RenderDelegate/imstkVTKSphereRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKCapsuleRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKSurfaceMeshRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKSurfaceNormalRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKTetrahedralMeshRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKHexahedralMeshRenderDelegate.cpp
VTKRenderer/RenderDelegate/imstkVTKCylinderRenderDelegate.cpp
...
...
Source/Rendering/Materials/imstkRenderMaterial.h
View file @
614e296e
...
...
@@ -49,7 +49,8 @@ public:
WireframeSurface
,
VolumeRendering
,
Fluid
,
///< Renders a set of points using a screen-space fluid renderer
Image
Image
,
SurfaceNormals
};
/// surface shading model. Defaults to Phong
...
...
Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKRenderDelegate.cpp
View file @
614e296e
...
...
@@ -36,6 +36,7 @@
#include
"imstkVTKCubeRenderDelegate.h"
#include
"imstkVTKCylinderRenderDelegate.h"
#include
"imstkVTKFluidRenderDelegate.h"
#include
"imstkVTKSurfaceNormalRenderDelegate.h"
#include
"imstkVTKHexahedralMeshRenderDelegate.h"
#include
"imstkVTKImageDataRenderDelegate.h"
#include
"imstkVTKLineMeshRenderDelegate.h"
...
...
@@ -73,6 +74,7 @@ VTKRenderDelegate::makeDelegate(std::shared_ptr<VisualModel> visualModel)
{
const
std
::
string
geomType
=
visualModel
->
getGeometry
()
->
getTypeName
();
// Two edge cases
if
(
visualModel
->
getRenderMaterial
()
->
getDisplayMode
()
==
RenderMaterial
::
DisplayMode
::
Fluid
)
{
if
(
std
::
dynamic_pointer_cast
<
PointSet
>
(
visualModel
->
getGeometry
())
!=
nullptr
)
...
...
@@ -80,14 +82,17 @@ VTKRenderDelegate::makeDelegate(std::shared_ptr<VisualModel> visualModel)
return
std
::
make_shared
<
VTKFluidRenderDelegate
>
(
visualModel
);
}
}
if
(
visualModel
->
getGeometry
()
->
isMesh
())
if
(
visualModel
->
getRenderMaterial
()
->
getDisplayMode
()
==
RenderMaterial
::
DisplayMode
::
SurfaceNormals
)
{
if
(
geomType
==
"PointSet"
)
if
(
std
::
dynamic_pointer_cast
<
PointSet
>
(
visualModel
->
getGeometry
())
!=
nullptr
)
{
return
std
::
make_shared
<
VTK
PointSet
RenderDelegate
>
(
visualModel
);
return
std
::
make_shared
<
VTK
SurfaceNormal
RenderDelegate
>
(
visualModel
);
}
else
if
(
geomType
==
"SurfaceMesh"
)
}
if
(
visualModel
->
getGeometry
()
->
isMesh
())
{
if
(
geomType
==
"SurfaceMesh"
)
{
return
std
::
make_shared
<
VTKSurfaceMeshRenderDelegate
>
(
visualModel
);
}
...
...
@@ -106,7 +111,11 @@ VTKRenderDelegate::makeDelegate(std::shared_ptr<VisualModel> visualModel)
}
else
{
if
(
geomType
==
"Plane"
)
if
(
geomType
==
"PointSet"
)
{
return
std
::
make_shared
<
VTKPointSetRenderDelegate
>
(
visualModel
);
}
else
if
(
geomType
==
"Plane"
)
{
return
std
::
make_shared
<
VTKPlaneRenderDelegate
>
(
visualModel
);
}
...
...
@@ -161,7 +170,7 @@ VTKRenderDelegate::makeDebugDelegate(std::shared_ptr<VisualModel> dbgVizModel)
}
default:
{
LOG
(
FATAL
)
<<
"error: Geometry type incorrect
/unsupported
"
;
LOG
(
FATAL
)
<<
"
RenderDelegate::makeDebugDelegate
error: Geometry type incorrect
.
"
;
return
nullptr
;
// will never be reached
}
}
...
...
Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKSurfaceNormalRenderDelegate.cpp
0 → 100644
View file @
614e296e
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#include
"imstkVTKSurfaceNormalRenderDelegate.h"
#include
"imstkPointSet.h"
#include
"imstkVisualModel.h"
#include
"imstkGeometryUtilities.h"
#include
"imstkRenderMaterial.h"
#include
"imstkLogger.h"
#include
"imstkSurfaceMesh.h"
#include
<vtkActor.h>
#include
<vtkDataArray.h>
#include
<vtkPointData.h>
#include
<vtkTransform.h>
#include
<vtkArrowSource.h>
#include
<vtkOpenGLGlyph3DMapper.h>
namespace
imstk
{
VTKSurfaceNormalRenderDelegate
::
VTKSurfaceNormalRenderDelegate
(
std
::
shared_ptr
<
VisualModel
>
visualModel
)
:
VTKPolyDataRenderDelegate
(
visualModel
),
m_polydata
(
vtkSmartPointer
<
vtkPolyData
>::
New
())
{
auto
surfMesh
=
std
::
static_pointer_cast
<
SurfaceMesh
>
(
visualModel
->
getGeometry
());
m_surfMeshVertices
=
surfMesh
->
getVertexPositions
();
m_surfMeshIndices
=
surfMesh
->
getTriangleIndices
();
// Compute the centers of the triangle
m_triangleCenterVertices
=
computeTriangleCenters
(
m_surfMeshVertices
,
m_surfMeshIndices
);
m_triangleNormals
=
computeTriangleNormals
(
m_surfMeshVertices
,
m_surfMeshIndices
);
// Map vertices to VTK point data
if
(
m_surfMeshVertices
!=
nullptr
)
{
m_mappedVertexArray
=
GeometryUtils
::
coupleVtkDataArray
(
m_triangleCenterVertices
);
auto
points
=
vtkSmartPointer
<
vtkPoints
>::
New
();
points
->
SetNumberOfPoints
(
m_triangleCenterVertices
->
size
());
points
->
SetData
(
m_mappedVertexArray
);
m_polydata
->
SetPoints
(
points
);
}
m_mappedNormalsArray
=
GeometryUtils
::
coupleVtkDataArray
(
m_triangleNormals
);
m_mappedNormalsArray
->
SetName
(
"ImageScalars"
);
m_polydata
->
GetPointData
()
->
SetVectors
(
m_mappedNormalsArray
);
// When geometry is modified, update data source, mostly for when an entirely new array/buffer was set
queueConnect
<
Event
>
(
surfMesh
,
&
Geometry
::
modified
,
this
,
&
VTKSurfaceNormalRenderDelegate
::
geometryModified
);
// When the vertex buffer internals are modified, ie: a single or N elements
queueConnect
<
Event
>
(
m_surfMeshVertices
,
&
AbstractDataArray
::
modified
,
this
,
&
VTKSurfaceNormalRenderDelegate
::
vertexDataModified
);
// Setup mapper
{
vtkNew
<
vtkArrowSource
>
arrowSource
;
arrowSource
->
Update
();
m_glyphPolyData
=
arrowSource
->
GetOutput
();
vtkNew
<
vtkOpenGLGlyph3DMapper
>
mapper
;
mapper
->
OrientOn
();
mapper
->
SetInputData
(
m_polydata
);
mapper
->
SetSourceData
(
m_glyphPolyData
);
mapper
->
SetOrientationArray
(
m_mappedNormalsArray
->
GetName
());
mapper
->
ScalingOn
();
mapper
->
SetScaleFactor
(
visualModel
->
getRenderMaterial
()
->
getPointSize
());
mapper
->
Update
();
vtkNew
<
vtkActor
>
actor
;
actor
->
SetMapper
(
mapper
);
actor
->
SetUserTransform
(
m_transform
);
m_mapper
=
mapper
;
m_actor
=
actor
;
}
update
();
updateRenderProperties
();
}
void
VTKSurfaceNormalRenderDelegate
::
processEvents
()
{
// Custom handling of events
std
::
shared_ptr
<
PointSet
>
geom
=
std
::
dynamic_pointer_cast
<
PointSet
>
(
m_visualModel
->
getGeometry
());
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
vertices
=
geom
->
getVertexPositions
();
// Only use the most recent event from respective sender
std
::
list
<
Command
>
cmds
;
bool
contains
[
4
]
=
{
false
,
false
,
false
,
false
};
rforeachEvent
([
&
](
Command
cmd
)
{
if
(
cmd
.
m_event
->
m_sender
==
m_visualModel
.
get
()
&&
!
contains
[
0
])
{
cmds
.
push_back
(
cmd
);
contains
[
0
]
=
true
;
}
else
if
(
cmd
.
m_event
->
m_sender
==
m_material
.
get
()
&&
!
contains
[
1
])
{
cmds
.
push_back
(
cmd
);
contains
[
1
]
=
true
;
}
else
if
(
cmd
.
m_event
->
m_sender
==
geom
.
get
()
&&
!
contains
[
2
])
{
cmds
.
push_back
(
cmd
);
contains
[
2
]
=
true
;
}
else
if
(
cmd
.
m_event
->
m_sender
==
vertices
.
get
()
&&
!
contains
[
3
])
{
cmds
.
push_back
(
cmd
);
contains
[
3
]
=
true
;
}
});
// Now do each event in order recieved
for
(
std
::
list
<
Command
>::
reverse_iterator
i
=
cmds
.
rbegin
();
i
!=
cmds
.
rend
();
i
++
)
{
i
->
invoke
();
}
}
void
VTKSurfaceNormalRenderDelegate
::
vertexDataModified
(
Event
*
imstkNotUsed
(
e
))
{
auto
geometry
=
std
::
static_pointer_cast
<
SurfaceMesh
>
(
m_visualModel
->
getGeometry
());
m_surfMeshVertices
=
geometry
->
getVertexPositions
();
// Compute the centers of the triangle
m_triangleCenterVertices
=
computeTriangleCenters
(
m_surfMeshVertices
,
m_surfMeshIndices
);
m_triangleNormals
=
computeTriangleNormals
(
m_surfMeshVertices
,
m_surfMeshIndices
);
m_mappedVertexArray
->
SetNumberOfComponents
(
3
);
m_mappedVertexArray
->
SetVoidArray
(
reinterpret_cast
<
double
*>
(
m_triangleCenterVertices
->
getPointer
()),
m_triangleCenterVertices
->
size
()
*
3
,
1
);
m_mappedVertexArray
->
Modified
();
m_mappedNormalsArray
->
SetNumberOfComponents
(
3
);
m_mappedNormalsArray
->
SetVoidArray
(
reinterpret_cast
<
double
*>
(
m_triangleNormals
->
getPointer
()),
m_triangleNormals
->
size
()
*
3
,
1
);
m_mappedNormalsArray
->
Modified
();
}
void
VTKSurfaceNormalRenderDelegate
::
geometryModified
(
Event
*
imstkNotUsed
(
e
))
{
// Called when the geometry posts modified
auto
geometry
=
std
::
static_pointer_cast
<
PointSet
>
(
m_visualModel
->
getGeometry
());
// Test if the vertex buffer changed
//if (m_surfMeshVertices != geometry->getVertexPositions())
{
vertexDataModified
(
nullptr
);
}
}
void
VTKSurfaceNormalRenderDelegate
::
updateRenderProperties
()
{
VTKPolyDataRenderDelegate
::
updateRenderProperties
();
vtkOpenGLGlyph3DMapper
::
SafeDownCast
(
m_mapper
)
->
SetScaleFactor
(
m_visualModel
->
getRenderMaterial
()
->
getPointSize
());
}
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
VTKSurfaceNormalRenderDelegate
::
computeTriangleCenters
(
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
verticesPtr
,
std
::
shared_ptr
<
VecDataArray
<
int
,
3
>>
indicesPtr
)
{
auto
newVerticesPtr
=
std
::
make_shared
<
VecDataArray
<
double
,
3
>>
(
indicesPtr
->
size
());
VecDataArray
<
double
,
3
>&
newVertices
=
*
newVerticesPtr
;
VecDataArray
<
double
,
3
>&
vertices
=
*
verticesPtr
;
VecDataArray
<
int
,
3
>&
indices
=
*
indicesPtr
;
const
double
ratio
=
1.0
/
3.0
;
for
(
int
i
=
0
;
i
<
indices
.
size
();
i
++
)
{
const
Vec3d
&
a
=
vertices
[
indices
[
i
][
0
]];
const
Vec3d
&
b
=
vertices
[
indices
[
i
][
1
]];
const
Vec3d
&
c
=
vertices
[
indices
[
i
][
2
]];
newVertices
[
i
]
=
(
a
+
b
+
c
)
*
ratio
;
}
return
newVerticesPtr
;
}
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
VTKSurfaceNormalRenderDelegate
::
computeTriangleNormals
(
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
verticesPtr
,
std
::
shared_ptr
<
VecDataArray
<
int
,
3
>>
indicesPtr
)
{
auto
orientationsPtr
=
std
::
make_shared
<
VecDataArray
<
double
,
3
>>
(
indicesPtr
->
size
());
VecDataArray
<
double
,
3
>&
orientations
=
*
orientationsPtr
;
VecDataArray
<
double
,
3
>&
vertices
=
*
verticesPtr
;
VecDataArray
<
int
,
3
>&
indices
=
*
indicesPtr
;
for
(
int
i
=
0
;
i
<
indices
.
size
();
i
++
)
{
const
Vec3d
&
a
=
vertices
[
indices
[
i
][
0
]];
const
Vec3d
&
b
=
vertices
[
indices
[
i
][
1
]];
const
Vec3d
&
c
=
vertices
[
indices
[
i
][
2
]];
orientations
[
i
]
=
(
c
-
a
).
cross
(
c
-
b
).
normalized
();
}
return
orientationsPtr
;
}
}
// imstk
Source/Rendering/VTKRenderer/RenderDelegate/imstkVTKSurfaceNormalRenderDelegate.h
0 → 100644
View file @
614e296e
/*=========================================================================
Library: iMSTK
Copyright (c) Kitware, Inc. & Center for Modeling, Simulation,
& Imaging in Medicine, Rensselaer Polytechnic Institute.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
#pragma once
#include
"imstkVTKPolyDataRenderDelegate.h"
class
vtkDataArray
;
class
vtkPolyData
;
namespace
imstk
{
class
PointSet
;
template
<
typename
T
,
int
N
>
class
VecDataArray
;
///
/// \class VTKSurfaceNormalRenderDelegate
///
/// \brief Renders normals as vectors from a surface mesh
///
class
VTKSurfaceNormalRenderDelegate
:
public
VTKPolyDataRenderDelegate
{
public:
///
/// \brief Constructor
///
VTKSurfaceNormalRenderDelegate
(
std
::
shared_ptr
<
VisualModel
>
visualModel
);
///
/// \brief Destructor
///
virtual
~
VTKSurfaceNormalRenderDelegate
()
override
=
default
;
///
/// \brief Update polydata source based on the mesh geometry
///
void
processEvents
()
override
;
protected:
///
/// \brief Callback for when vertex data changes
///
void
vertexDataModified
(
Event
*
e
);
///
/// \brief Callback for when geometry changes
///
void
geometryModified
(
Event
*
e
);
///
/// \brief Updates the actor and mapper properties from the currently set VisualModel
///
virtual
void
updateRenderProperties
()
override
;
///
/// \brief Computes triangle centers from the current geometry
///
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
computeTriangleCenters
(
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
verticesPtr
,
std
::
shared_ptr
<
VecDataArray
<
int
,
3
>>
indicesPtr
);
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
computeTriangleNormals
(
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
verticesPtr
,
std
::
shared_ptr
<
VecDataArray
<
int
,
3
>>
indicesPtr
);
protected:
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
m_surfMeshVertices
;
std
::
shared_ptr
<
VecDataArray
<
int
,
3
>>
m_surfMeshIndices
;
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
m_triangleCenterVertices
;
std
::
shared_ptr
<
VecDataArray
<
double
,
3
>>
m_triangleNormals
;
vtkSmartPointer
<
vtkPolyData
>
m_polydata
;
vtkSmartPointer
<
vtkPolyData
>
m_glyphPolyData
;
vtkSmartPointer
<
vtkDataArray
>
m_mappedVertexArray
;
///> Mapped array of vertices
vtkSmartPointer
<
vtkDataArray
>
m_mappedNormalsArray
;
///> Mapped array of orientations
};
}
Source/SceneEntities/Objects/imstkVisualModel.cpp
View file @
614e296e
...
...
@@ -46,6 +46,10 @@ VisualModel::VisualModel(std::shared_ptr<DebugRenderGeometry> geometry,
{
}
VisualModel
::
VisualModel
()
:
m_renderMaterial
(
std
::
make_shared
<
RenderMaterial
>
())
{
}
bool
VisualModel
::
getRenderDelegateCreated
(
Renderer
*
ren
)
{
...
...
Source/SceneEntities/Objects/imstkVisualModel.h
View file @
614e296e
...
...
@@ -51,7 +51,7 @@ public:
VisualModel
(
std
::
shared_ptr
<
DebugRenderGeometry
>
geometry
);
VisualModel
(
std
::
shared_ptr
<
DebugRenderGeometry
>
geometry
,
std
::
shared_ptr
<
RenderMaterial
>
renderMaterial
);
VisualModel
()
=
default
;
VisualModel
();
virtual
~
VisualModel
()
override
=
default
;
public:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment