[Closed] distance color map problems
Hello everybody,
i am trying to compare two models of terrain with a color map. i am doing this with an adapted example in maxscript of the RayMeshGridIntersect method.
The problem is, when it comes to the function for assigning the vertex color it seems it gets an memory leak. and my second question how can i optimize/speed this script up. because for 80000 vertices it takes my computer 48 seconds to calcalute the distances. The code it below and it already creates to planes as an example. If somebody has an idea or advise, all help is appreciated
clearlistener()
----------------VARIABLE-------------
global MaxDistance = 30
global dist_color = (240 / MaxDistance)
global vertex_color_array = #()
global face_index_VC = #()
global rmGRID
global vertex_color_assign
global update_vertex_color_model
-------------------------------FUNCTIONS---------------------------------------
(
fn distancemap_init =
(
global dist_max = 0
global rm = RayMeshGridIntersect() --create an instance of the Reference Target
rm.free() --leeg het voxel grid en bouw daarna een grid op
global fastgridsize = (((theRefSnapShot.numfaces / 250.0) + 2) as integer)
rm.initialize (if (fastgridsize<=500) then fastgridsize else 500)
rm.addNode theTarget --add the sphere to the grid
rm.buildGrid() --build the grid data (collecting faces into the grid voxels)
)
fn rmGRID =
(
for v = 1 to theRefSnapShot.numverts do --go through all verts of the Geosphere
(
thePos = getVert theRefSnapShot v --get the position of the vertex
theNormal = -(getNormal theRefSnapShot v) --get the normal of the vertex, reverse direction
theHitsCount = rm.intersectRay thePos theNormal true --intersect the ray with the sphere
if theHitsCount != 0 then --if have hit anything...
(
theIndex = rm.getClosestHit() --get the index of the closest hit by the ray
theFace = rm.getHitFace theIndex --get the face index corresponding to that indexed hit
dist = rm.getHitDist theIndex
if dist < MaxDistance then
(
color_vertex = 255 - (dist * dist_color)
--red if negative normale distance
append vertex_color_array (color 255 color_vertex color_vertex)
append face_index_VC theFace
)
else
(
--black if no distance
append vertex_color_array (color 0 0 0)
append face_index_VC theFace
)
)
else
(
theNormal = (getNormal theRefSnapShot v) --get the normal of the vertex, reverse direction
theHitsCount = rm.intersectRay thePos theNormal true --intersect the ray with the sphere
if theHitsCount != 0 then --if have hit anything...
(
theIndex = rm.getClosestHit() --get the index of the closest hit by the ray
theFace = rm.getHitFace theIndex --get the face index corresponding to that indexed hit
dist = rm.getHitDist theIndex
if dist < MaxDistance then
(
color_vertex = 255 - (dist * dist_color)
--green if positive normale distance
append vertex_color_array (color color_vertex 255 color_vertex)
append face_index_VC theFace
)
else
(
--black if no distance
append vertex_color_array (color 0 0 0)
append face_index_VC theFace
)
)
)
)
)
------------assign vertex color-------------------------
fn vertex_color_assign =
(
count = face_index_VC.count
for i = 1 to count do
(
x = getface theTarget face_index_VC[i] --get facenumber van het object
meshop.setvertColor theTarget 0 x[1] vertex_color_array[i]--3 punt vertex met kleur toekenning
meshop.setvertColor theTarget 0 x[2] vertex_color_array[i]
meshop.setvertColor theTarget 0 x[3] vertex_color_array[i]
)
)
------------refresh model with vertex color
fn update_vertex_color_model =
(
theTarget.showvertexcolors=true
theTarget.vertexColorsShaded=true
update theTarget
)
)
-----------------------------------------------------------------------
--create 2 test planes to compare distance of eachother by color
global planes = #()
for x = 1 to 2 do
(
naam = uniquename "plane_" + x as string
print obj
obj = plane name:naam width:200 length:200 lengthsegs:50 widthsegs:50
noise_mod = noisemodifier seed:(random 0 50) fractal:true roughness:0.3 strength:[0,0,30] iterations:4
addmodifier obj noise_mod
converttomesh obj
append planes obj
)
global TheTarget = planes[1]
global theRefSnapShot = planes[2]
---------------------------------------------------------------------------
--start
undo off
t1 = timestamp()
distancemap_init ()
t2 = timestamp()
rmGRID()
t3 = timestamp()
vertex_color_assign()
t4 = timestamp()
update_vertex_color_model()
t5 = timestamp()
GC(distancemap_init)
GC(init_rmGRID_minus)
GC(update_vertex_color_model)
format "Init took % seconds
" ((t2 - t1) / 1000.0)
format "distances measurement % seconds
" ((t3 - t2) / 1000.0)
format "apply vertex color took % seconds
" ((t4 - t3) / 1000.0)
format "update model took % seconds
" ((t5 - t4) / 1000.0)
format "total time % seconds
" ((t5 - t1) / 1000)
If you are storing colors by face, why are you assigning them by color?
Wouldn’t this give you the same result:
fn vertex_color_assign =
(
count = face_index_VC.count
local sfc = meshop.setFaceColor
for i = 1 to count do
(
sfc theTarget 0 #{face_index_VC[i]} vertex_color_array[i]
)
)
Hello Lo,
thank you for your idea, the code is faster then what i had, but my reason for not assigning the color to the face is that the result is not looking good. in the image below you can see on the left side vertex assignment and on the right side face assignment. the vertex color has a better transition between colors.
well… staying within your methodology, this is about 3 times faster for vertex color assignment. Haven’t looked at the other parts yet:
fn vertex_color_assign =
(
count = face_index_VC.count
svc = meshop.setVertColor
for i = 1 to count do
(
x = getface theTarget face_index_VC[i] --get facenumber van het object
va = #{x[1],x[2],x[3]}
svc theTarget 0 va vertex_color_array[i]--3 punt vertex met kleur toekenning
)
)
In general, one way to dramatically speed up vertex color assignments is to do as few of them as possible.
A method I once used was the following:
instead of saving a color for each vertex, save a list of vertices for each color.
This is not useful if you have many different colors, but for example, if you’re just using a grayscale 0-255 range, the most vertex color assignments you’ll have is 256, no matter how many vertices in the mesh.
Hi Lo
:-), super, thank you. That is indeed alot faster.
And the idea for saving a vertex list for each color is a smart idea. I will have a look into it today.
Perhaps you could also help me with another problem, because when i only have like 10000 verts in total for the model, the code works fine. But when i want to have like 40000 or more vertices i start to get an “system exception” and the application closes. Perhaps you have an idea what could be the problem with this?
I haven’t thoroughly read your code yet, but make sure you have enough memory on the heap. Try to increase your heapsize and see if it makes a difference.