Merge branch 'develop' into feature/large-volume-work
This commit is contained in:
commit
36968bdd79
@ -82,6 +82,7 @@ IF(ENABLE_EXAMPLES AND QT_QTOPENGL_FOUND)
|
|||||||
ADD_SUBDIRECTORY(examples/Paging)
|
ADD_SUBDIRECTORY(examples/Paging)
|
||||||
ADD_SUBDIRECTORY(examples/OpenGL)
|
ADD_SUBDIRECTORY(examples/OpenGL)
|
||||||
ADD_SUBDIRECTORY(examples/SmoothLOD)
|
ADD_SUBDIRECTORY(examples/SmoothLOD)
|
||||||
|
ADD_SUBDIRECTORY(examples/Python)
|
||||||
SET(BUILD_EXAMPLES ON)
|
SET(BUILD_EXAMPLES ON)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(BUILD_EXAMPLES OFF)
|
SET(BUILD_EXAMPLES OFF)
|
||||||
|
26
examples/Python/CMakeLists.txt
Normal file
26
examples/Python/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (c) 2010-2013 Matt Williams
|
||||||
|
#
|
||||||
|
# This software is provided 'as-is', without any express or implied
|
||||||
|
# warranty. In no event will the authors be held liable for any damages
|
||||||
|
# arising from the use of this software.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
#
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
#
|
||||||
|
# 3. This notice may not be removed or altered from any source
|
||||||
|
# distribution.
|
||||||
|
|
||||||
|
PROJECT(PythonExample)
|
||||||
|
|
||||||
|
SOURCE_GROUP("Sources" FILES PythonExample.py)
|
||||||
|
|
||||||
|
configure_file(PythonExample.py PythonExample.py COPYONLY)
|
257
examples/Python/PythonExample.py
Executable file
257
examples/Python/PythonExample.py
Executable file
@ -0,0 +1,257 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Copyright (c) 2013 Matt Williams
|
||||||
|
#
|
||||||
|
# This software is provided 'as-is', without any express or implied
|
||||||
|
# warranty. In no event will the authors be held liable for any damages
|
||||||
|
# arising from the use of this software.
|
||||||
|
#
|
||||||
|
# Permission is granted to anyone to use this software for any purpose,
|
||||||
|
# including commercial applications, and to alter it and redistribute it
|
||||||
|
# freely, subject to the following restrictions:
|
||||||
|
#
|
||||||
|
# 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
# claim that you wrote the original software. If you use this software
|
||||||
|
# in a product, an acknowledgment in the product documentation would be
|
||||||
|
# appreciated but is not required.
|
||||||
|
#
|
||||||
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
# misrepresented as being the original software.
|
||||||
|
#
|
||||||
|
# 3. This notice may not be removed or altered from any source
|
||||||
|
# distribution.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append("../../library/bindings/") #This is just to point to the generated bindings
|
||||||
|
|
||||||
|
import PolyVoxCore as pv
|
||||||
|
|
||||||
|
#Create a 64x64x64 volume of integers
|
||||||
|
r = pv.Region(pv.Vector3Dint32_t(0,0,0), pv.Vector3Dint32_t(63,63,63))
|
||||||
|
vol = pv.SimpleVolumeuint8(r)
|
||||||
|
|
||||||
|
#Now fill the volume with our data (a sphere)
|
||||||
|
v3dVolCenter = pv.Vector3Dint32_t(vol.getWidth() / 2, vol.getHeight() / 2, vol.getDepth() / 2)
|
||||||
|
sphereRadius = 30
|
||||||
|
#This three-level for loop iterates over every voxel in the volume
|
||||||
|
for z in range(vol.getDepth()):
|
||||||
|
for y in range(vol.getHeight()):
|
||||||
|
for x in range(vol.getWidth()):
|
||||||
|
#Store our current position as a vector...
|
||||||
|
v3dCurrentPos = pv.Vector3Dint32_t(x,y,z)
|
||||||
|
#And compute how far the current position is from the center of the volume
|
||||||
|
fDistToCenter = (v3dCurrentPos - v3dVolCenter).length()
|
||||||
|
|
||||||
|
uVoxelValue = 0
|
||||||
|
|
||||||
|
#If the current voxel is less than 'radius' units from the center then we make it solid.
|
||||||
|
if(fDistToCenter <= sphereRadius):
|
||||||
|
#Our new voxel value
|
||||||
|
uVoxelValue = 255
|
||||||
|
|
||||||
|
#Write the voxel value into the volume
|
||||||
|
vol.setVoxelAt(x, y, z, uVoxelValue);
|
||||||
|
|
||||||
|
#Create a mesh, pass it to the extractor and generate the mesh
|
||||||
|
mesh = pv.SurfaceMeshPositionMaterialNormal()
|
||||||
|
extractor = pv.CubicSurfaceExtractorWithNormalsSimpleVolumeuint8(vol, r, mesh)
|
||||||
|
extractor.execute()
|
||||||
|
|
||||||
|
#That's all of the PolyVox generation done, now to convert the output to something OpenGL can read efficiently
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
indices = np.array(mesh.getIndices(), dtype='uint32') #Throw in the vertex indices into an array
|
||||||
|
#The vertices and normals are placed in an interpolated array like [vvvnnn,vvvnnn,vvvnnn]
|
||||||
|
vertices = np.array([[vertex.getPosition().getX(), vertex.getPosition().getY(), vertex.getPosition().getZ(),
|
||||||
|
vertex.getNormal().getX(), vertex.getNormal().getY(), vertex.getNormal().getZ()]
|
||||||
|
for vertex in mesh.getVertices()],
|
||||||
|
dtype='f')
|
||||||
|
|
||||||
|
#Now that we have our data, everything else here is just OpenGL
|
||||||
|
|
||||||
|
import OpenGL
|
||||||
|
|
||||||
|
from OpenGL.GL import shaders
|
||||||
|
from OpenGL.arrays import vbo
|
||||||
|
from OpenGL.GL import glClear, glEnable, glDepthFunc, GLuint, glEnableVertexAttribArray, glVertexAttribPointer, glDisableVertexAttribArray, \
|
||||||
|
glDrawElements, glGetUniformLocation, glUniformMatrix4fv, glDepthMask, glDepthRange, glGetString, glBindAttribLocation, \
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_TRIANGLES, GL_DEPTH_TEST, GL_LEQUAL, GL_FLOAT, \
|
||||||
|
GL_DEPTH_BUFFER_BIT, GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, GL_STATIC_DRAW, \
|
||||||
|
GL_FALSE, GL_TRUE, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_CULL_FACE, \
|
||||||
|
GL_VENDOR, GL_RENDERER, GL_VERSION, GL_SHADING_LANGUAGE_VERSION
|
||||||
|
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from math import sin, cos, tan, radians
|
||||||
|
|
||||||
|
SCREEN_SIZE = (800, 800)
|
||||||
|
|
||||||
|
def run():
|
||||||
|
#Start OpenGL and ask it for an OpenGL context
|
||||||
|
pygame.init()
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF)
|
||||||
|
|
||||||
|
#The first thing we do is print some OpenGL details and check that we have a good enough version
|
||||||
|
print "OpenGL Implementation Details:"
|
||||||
|
if glGetString(GL_VENDOR):
|
||||||
|
print "\tGL_VENDOR:", glGetString(GL_VENDOR)
|
||||||
|
if glGetString(GL_RENDERER):
|
||||||
|
print "\tGL_RENDERER:", glGetString(GL_RENDERER)
|
||||||
|
if glGetString(GL_VERSION):
|
||||||
|
print "\tGL_VERSION:", glGetString(GL_VERSION)
|
||||||
|
if glGetString(GL_SHADING_LANGUAGE_VERSION):
|
||||||
|
print "\tGL_SHADING_LANGUAGE_VERSION:", glGetString(GL_SHADING_LANGUAGE_VERSION)
|
||||||
|
|
||||||
|
major_version = int(glGetString(GL_VERSION).split()[0].split('.')[0])
|
||||||
|
minor_version = int(glGetString(GL_VERSION).split()[0].split('.')[1])
|
||||||
|
if major_version < 3 or (major_version < 3 and minor_version < 0):
|
||||||
|
print "OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).split()[0])
|
||||||
|
|
||||||
|
#Now onto the OpenGL initialisation
|
||||||
|
|
||||||
|
#Set up depth culling
|
||||||
|
glEnable(GL_CULL_FACE)
|
||||||
|
glEnable(GL_DEPTH_TEST)
|
||||||
|
glDepthMask(GL_TRUE)
|
||||||
|
glDepthFunc(GL_LEQUAL)
|
||||||
|
glDepthRange(0.0, 1.0)
|
||||||
|
|
||||||
|
#We create out shaders which do little more than set a flat colour for each face
|
||||||
|
|
||||||
|
VERTEX_SHADER = shaders.compileShader("""
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
in vec4 position;
|
||||||
|
in vec4 normal;
|
||||||
|
|
||||||
|
uniform mat4 cameraToClipMatrix;
|
||||||
|
uniform mat4 worldToCameraMatrix;
|
||||||
|
uniform mat4 modelToWorldMatrix;
|
||||||
|
|
||||||
|
flat out float theColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 temp = modelToWorldMatrix * position;
|
||||||
|
temp = worldToCameraMatrix * temp;
|
||||||
|
gl_Position = cameraToClipMatrix * temp;
|
||||||
|
|
||||||
|
theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1);
|
||||||
|
}
|
||||||
|
""", GL_VERTEX_SHADER)
|
||||||
|
|
||||||
|
FRAGMENT_SHADER = shaders.compileShader("""
|
||||||
|
#version 130
|
||||||
|
|
||||||
|
flat in float theColor;
|
||||||
|
|
||||||
|
out vec4 outputColor;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outputColor = vec4(1.0, 0.5, theColor, 1.0);
|
||||||
|
}
|
||||||
|
""", GL_FRAGMENT_SHADER)
|
||||||
|
|
||||||
|
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
|
||||||
|
|
||||||
|
#And then grab our attribute locations from it
|
||||||
|
glBindAttribLocation(shader, 0, "position")
|
||||||
|
glBindAttribLocation(shader, 1, "normal")
|
||||||
|
|
||||||
|
#Create the Vertex Array Object to hold our volume mesh
|
||||||
|
vertexArrayObject = GLuint(0)
|
||||||
|
glGenVertexArrays(1, vertexArrayObject)
|
||||||
|
glBindVertexArray(vertexArrayObject)
|
||||||
|
|
||||||
|
#Create the index buffer object
|
||||||
|
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER, usage=GL_STATIC_DRAW)
|
||||||
|
#Create the VBO
|
||||||
|
vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW)
|
||||||
|
|
||||||
|
#Bind our VBOs and set up our data layout specifications
|
||||||
|
with indexPositions, vertexPositions:
|
||||||
|
glEnableVertexAttribArray(0)
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(0*vertices.dtype.itemsize))
|
||||||
|
glEnableVertexAttribArray(1)
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(3*vertices.dtype.itemsize))
|
||||||
|
|
||||||
|
glBindVertexArray(0)
|
||||||
|
glDisableVertexAttribArray(0)
|
||||||
|
|
||||||
|
#Now grab out transformation martix locations
|
||||||
|
modelToWorldMatrixUnif = glGetUniformLocation(shader, "modelToWorldMatrix")
|
||||||
|
worldToCameraMatrixUnif = glGetUniformLocation(shader, "worldToCameraMatrix")
|
||||||
|
cameraToClipMatrixUnif = glGetUniformLocation(shader, "cameraToClipMatrix")
|
||||||
|
|
||||||
|
modelToWorldMatrix = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
worldToCameraMatrix = np.array([[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,-50.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
cameraToClipMatrix = np.array([[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0]], dtype='f')
|
||||||
|
|
||||||
|
#These next few lines just set up our camera frustum
|
||||||
|
fovDeg = 45.0
|
||||||
|
frustumScale = 1.0 / tan(radians(fovDeg) / 2.0)
|
||||||
|
|
||||||
|
zNear = 1.0
|
||||||
|
zFar = 1000.0
|
||||||
|
|
||||||
|
cameraToClipMatrix[0][0] = frustumScale
|
||||||
|
cameraToClipMatrix[1][1] = frustumScale
|
||||||
|
cameraToClipMatrix[2][2] = (zFar + zNear) / (zNear - zFar)
|
||||||
|
cameraToClipMatrix[2][3] = -1.0
|
||||||
|
cameraToClipMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar)
|
||||||
|
|
||||||
|
#worldToCameraMatrix and cameraToClipMatrix don't change ever so just set them once here
|
||||||
|
with shader:
|
||||||
|
glUniformMatrix4fv(cameraToClipMatrixUnif, 1, GL_TRUE, cameraToClipMatrix)
|
||||||
|
glUniformMatrix4fv(worldToCameraMatrixUnif, 1, GL_TRUE, worldToCameraMatrix)
|
||||||
|
|
||||||
|
#These are used to track the rotation of the volume
|
||||||
|
LastFrameMousePos = (0,0)
|
||||||
|
CurrentMousePos = (0,0)
|
||||||
|
xRotation = 0
|
||||||
|
yRotation = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
clock.tick()
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
return
|
||||||
|
if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
|
||||||
|
return
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
||||||
|
CurrentMousePos = event.pos
|
||||||
|
LastFrameMousePos = CurrentMousePos
|
||||||
|
if event.type == pygame.MOUSEMOTION and 1 in event.buttons:
|
||||||
|
CurrentMousePos = event.pos
|
||||||
|
diff = (CurrentMousePos[0] - LastFrameMousePos[0], CurrentMousePos[1] - LastFrameMousePos[1])
|
||||||
|
xRotation += event.rel[0]
|
||||||
|
yRotation += event.rel[1]
|
||||||
|
LastFrameMousePos = CurrentMousePos
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
|
#Perform the rotation of the mesh
|
||||||
|
moveToOrigin = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
rotateAroundX = np.array([[1.0,0.0,0.0,0.0],[0.0,cos(radians(yRotation)),-sin(radians(yRotation)),0.0],[0.0,sin(radians(yRotation)),cos(radians(yRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
rotateAroundY = np.array([[cos(radians(xRotation)),0.0,sin(radians(xRotation)),0.0],[0.0,1.0,0.0,0.0],[-sin(radians(xRotation)),0.0,cos(radians(xRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f')
|
||||||
|
|
||||||
|
modelToWorldMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin))
|
||||||
|
|
||||||
|
with shader:
|
||||||
|
glUniformMatrix4fv(modelToWorldMatrixUnif, 1, GL_TRUE, modelToWorldMatrix)
|
||||||
|
glBindVertexArray(vertexArrayObject)
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)
|
||||||
|
|
||||||
|
glBindVertexArray(0)
|
||||||
|
|
||||||
|
# Show the screen
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
run()
|
@ -26,13 +26,12 @@ namespace PolyVox
|
|||||||
// We try to avoid duplicate vertices by checking whether a vertex has already been added at a given position.
|
// We try to avoid duplicate vertices by checking whether a vertex has already been added at a given position.
|
||||||
// However, it is possible that vertices have the same position but different materials. In this case, the
|
// However, it is possible that vertices have the same position but different materials. In this case, the
|
||||||
// vertices are not true duplicates and both must be added to the mesh. As far as I can tell, it is possible to have
|
// vertices are not true duplicates and both must be added to the mesh. As far as I can tell, it is possible to have
|
||||||
// at most six vertices with the same position but different materials. This worst-case scenario happens when we
|
// at most eight vertices with the same position but different materials. For example, this worst-case scenario
|
||||||
// have a 2x2x2 group of voxels (all with different materials) and then we delete two voxels from opposing corners.
|
// happens when we have a 2x2x2 group of voxels, all with different materials and some/all partially transparent.
|
||||||
// The vertex position at the center of this group is then going to be used by six quads all with different materials.
|
// The vertex position at the center of this group is then going to be used by all eight voxels all with different
|
||||||
// One futher note - we can actually have eight quads sharing a vertex position (imagine two 1x1x10 rows of voxels
|
// materials.
|
||||||
// sharing a common edge) but in this case all eight quads will not have different materials.
|
|
||||||
template<typename VolumeType, typename IsQuadNeeded>
|
template<typename VolumeType, typename IsQuadNeeded>
|
||||||
const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 6;
|
const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 8;
|
||||||
|
|
||||||
template<typename VolumeType, typename IsQuadNeeded>
|
template<typename VolumeType, typename IsQuadNeeded>
|
||||||
CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial>* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)
|
CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::CubicSurfaceExtractor(VolumeType* volData, Region region, SurfaceMesh<PositionMaterial>* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
|
|
||||||
%include "CubicSurfaceExtractor.h"
|
%include "CubicSurfaceExtractor.h"
|
||||||
|
|
||||||
EXTRACTORS(CubicSurfaceExtractor)
|
%template(CubicSurfaceExtractorSimpleVolumeuint8) PolyVox::CubicSurfaceExtractor<PolyVox::SimpleVolume<uint8_t>, PolyVox::DefaultIsQuadNeeded<uint8_t> >;
|
||||||
|
//EXTRACTORS(CubicSurfaceExtractor)
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
%module CubicSurfaceExtractorWithNormals
|
%module CubicSurfaceExtractorWithNormals
|
||||||
%{
|
%{
|
||||||
#include "SimpleVolume.h"
|
|
||||||
//#include "CubicSurfaceExtractor.h"
|
|
||||||
#include "CubicSurfaceExtractorWithNormals.h"
|
#include "CubicSurfaceExtractorWithNormals.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "SimpleVolume.h"
|
|
||||||
//%include "CubicSurfaceExtractor.h"
|
|
||||||
%include "CubicSurfaceExtractorWithNormals.h"
|
%include "CubicSurfaceExtractorWithNormals.h"
|
||||||
|
|
||||||
%template(CubicSurfaceExtractorWithNormalsMaterial8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::Material8>;
|
%template(CubicSurfaceExtractorWithNormalsSimpleVolumeuint8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::SimpleVolume<uint8_t>, PolyVox::DefaultIsQuadNeeded<uint8_t> >;
|
||||||
%template(CubicSurfaceExtractorWithNormalsDensity8) PolyVox::CubicSurfaceExtractorWithNormals<PolyVox::Density8>;
|
|
||||||
|
@ -84,5 +84,6 @@ EXTRACTOR(shortname, LargeVolume)
|
|||||||
%include "VertexTypes.i"
|
%include "VertexTypes.i"
|
||||||
%include "SurfaceMesh.i"
|
%include "SurfaceMesh.i"
|
||||||
%include "MarchingCubesSurfaceExtractor.i"
|
%include "MarchingCubesSurfaceExtractor.i"
|
||||||
//%include "CubicSurfaceExtractor.i"
|
%include "CubicSurfaceExtractor.i"
|
||||||
|
%include "CubicSurfaceExtractorWithNormals.i"
|
||||||
%include "Raycast.i"
|
%include "Raycast.i"
|
||||||
|
@ -12,7 +12,15 @@ PROPERTY(PolyVox::Vector, y, getY, setY)
|
|||||||
PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
%rename(Plus) operator +;
|
||||||
|
%rename(Minus) operator -;
|
||||||
|
%rename(Multiply) operator *;
|
||||||
|
%rename(Divide) operator /;
|
||||||
|
%rename(Equal) operator ==;
|
||||||
|
%rename(NotEqual) operator !=;
|
||||||
|
|
||||||
%extend PolyVox::Vector {
|
%extend PolyVox::Vector {
|
||||||
|
#ifdef SWIGPYTHON
|
||||||
PolyVox::Vector __add__(const PolyVox::Vector& rhs) {
|
PolyVox::Vector __add__(const PolyVox::Vector& rhs) {
|
||||||
return *$self + rhs;
|
return *$self + rhs;
|
||||||
}
|
}
|
||||||
@ -31,6 +39,7 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
|||||||
PolyVox::Vector __mul__(const StorageType& rhs) {
|
PolyVox::Vector __mul__(const StorageType& rhs) {
|
||||||
return *$self * rhs;
|
return *$self * rhs;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
STR()
|
STR()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,12 +51,62 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ)
|
|||||||
//%csattributes PolyVox::Vector::operator< "[System.Obsolete(\"deprecated\")]"
|
//%csattributes PolyVox::Vector::operator< "[System.Obsolete(\"deprecated\")]"
|
||||||
|
|
||||||
%define VECTOR3(StorageType,OperationType,ReducedStorageType)
|
%define VECTOR3(StorageType,OperationType,ReducedStorageType)
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
#if SWIGCSHARP
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType);
|
%extend PolyVox::Vector<3,StorageType,OperationType> {
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const;
|
PolyVox::Vector<3,StorageType,OperationType> operator+(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self + rhs;}
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType);
|
PolyVox::Vector<3,StorageType,OperationType> operator-(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self - rhs;}
|
||||||
%ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
PolyVox::Vector<3,StorageType,OperationType> operator*(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self * rhs;}
|
||||||
%template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>;
|
PolyVox::Vector<3,StorageType,OperationType> operator/(const PolyVox::Vector<3,StorageType,OperationType>& rhs) {return *$self / rhs;}
|
||||||
|
PolyVox::Vector<3,StorageType,OperationType> operator*(const StorageType& rhs) {return *$self * rhs;}
|
||||||
|
PolyVox::Vector<3,StorageType,OperationType> operator/(const StorageType& rhs) {return *$self / rhs;}
|
||||||
|
};
|
||||||
|
%typemap(cscode) PolyVox::Vector<3,StorageType,OperationType> %{
|
||||||
|
public static Vector3D##StorageType operator+(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Plus(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator-(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Minus(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Multiply(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, Vector3D##StorageType rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Divide(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator*(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Multiply(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public static Vector3D##StorageType operator/(Vector3D##StorageType lhs, $typemap(cstype, StorageType) rhs) {
|
||||||
|
Vector3D##StorageType newVec = new Vector3D##StorageType();
|
||||||
|
newVec = lhs.Divide(rhs);
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
public bool Equals(Vector3D##StorageType rhs) {
|
||||||
|
if ((object)rhs == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Equal(rhs);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::operator<; //This is deprecated
|
||||||
|
#endif
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::Vector(ReducedStorageType,ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::getW() const;
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::setW(ReducedStorageType);
|
||||||
|
%ignore PolyVox::Vector<3,StorageType,OperationType>::setElements(ReducedStorageType,ReducedStorageType,ReducedStorageType,ReducedStorageType);
|
||||||
|
%template(Vector3D ## StorageType) PolyVox::Vector<3,StorageType,OperationType>;
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
VECTOR3(float,float,float)
|
VECTOR3(float,float,float)
|
||||||
|
32
tests/TestSurfaceExtractor.cs
Normal file
32
tests/TestSurfaceExtractor.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
public class test
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
Region r = new Region(new Vector3Dint32_t(0,0,0), new Vector3Dint32_t(31,31,31));
|
||||||
|
SimpleVolumeuint8 vol = new SimpleVolumeuint8(r);
|
||||||
|
//Set one single voxel to have a reasonably high density
|
||||||
|
vol.setVoxelAt(new Vector3Dint32_t(5, 5, 5), 200);
|
||||||
|
SurfaceMeshPositionMaterialNormal mesh = new SurfaceMeshPositionMaterialNormal();
|
||||||
|
MarchingCubesSurfaceExtractorSimpleVolumeuint8 extractor = new MarchingCubesSurfaceExtractorSimpleVolumeuint8(vol, r, mesh);
|
||||||
|
extractor.execute();
|
||||||
|
|
||||||
|
Debug.Assert(mesh.getNoOfVertices() == 6);
|
||||||
|
|
||||||
|
Vector3Dint32_t v1 = new Vector3Dint32_t(1,2,3);
|
||||||
|
Vector3Dint32_t v2 = new Vector3Dint32_t(6,8,12);
|
||||||
|
Vector3Dint32_t v3 = v1 + v2;
|
||||||
|
|
||||||
|
Vector3Dint32_t v11 = new Vector3Dint32_t(1,2,3);
|
||||||
|
|
||||||
|
Debug.Assert(v3.getX() == 7);
|
||||||
|
Debug.Assert((v3*5).getX() == 35);
|
||||||
|
Debug.Assert(v1.Equals(v11));
|
||||||
|
Debug.Assert(v1 != v11);
|
||||||
|
Debug.Assert(!v1.Equals(v2));
|
||||||
|
Debug.Assert(!v1.Equals(null));
|
||||||
|
|
||||||
|
System.Console.WriteLine("Success");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user