Page 1 of 1

models from point clouds

Posted: Fri May 24, 2013 3:46 pm
by applePi
i have posted in the MP3D pages http://www.purebasic.fr/english/viewtop ... &start=375 how to convert point clouds to model using MeshLab free program.
in purebasic Ogre we can save the mesh made from points using SaveMesh(#Mesh, Filename$) with full color, but we can't use it with physics engine since we need to connect the points with triangles.
in the following program it display 100000 points of mandel 3D then it saves the points coordinates to dataxyz.asc, it is just a text data. the important 2 lines are:
MeshVertexColor(RGB(red,green,blue))
a$=StrF(x)+ "," +StrF(y)+"," +StrF(z)
WriteStringN(1, a$)

i don't know how to add colors to points in file dataxyz.asc so MeshLab can manipulate the colors, i will continue experimenting

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA
   #BUTTON
   #mainwin
 EndEnumeration
 
Global.f dx, dy, x, y, z
Global wd, ht, i, count, n, iter
Global.f w, leng, tx, ty, tz, tem
Global.f cr, ci, cj, ck, wk, inc, distance
Global mand, zval
Global.f angle
Define.f red, green, blue
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
wd = 500
ht = 500
;defines the shape of the Julia Set
cr = -0.200
ci = 0.800
cj = 0.000
ck = 0.000
wk = 0.000
;mand = 0 is Julia Set
;mand = 1 is Mandelbrot 3D
mand = 1
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
zval = 1
iter = 5
inc = 5 
;#quat = 1
zval = 1
iter = 5
inc = 5 
Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure

Quit.b = #False
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=1:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 2.2: depth.f=0

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "the mesh now saved from points list to file dataxyz.asc - exit the program if you want", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop") 

;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
WorldShadows(#PB_Shadow_Additive)

InitKeyboard()
SetFrameRate(60)

Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(#CAMERA, 0, 0, 400, 400)
MoveCamera(#CAMERA, 0, 4, 9)
CameraLookAt(#CAMERA, 0, 2, 0)

RotateCamera(#CAMERA, -15, 0, 0)
EndIf

SetActiveGadget(#BUTTON)
;SkyDome("clouds.jpg", 100) ;for blue color background

;;9999999999999999999999999999999999999999999999999999999
CreateTexture(0,16,16)
StartDrawing(TextureOutput(0))
Box(0, 0, 16, 16,RGB(255,255,255))
StopDrawing()

CreateMaterial(0, TextureID(0))
DisableMaterialLighting(0, #True)
;- Mesh Points
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static )
;SetMeshMaterial(1, MaterialID(0))

;99999999999999999999999999999999999999999999999999999999

Procedure.f calcleng( x.f,  y.f,  z.f)
    w.f: kr.f: ki.f: kj.f: kk.f
    w = wk
    n = 0
    If mand = 1  ;full Mandelbrot set
        kr = x
        ki = y
        kj = z
        kk = 0
    Else                ;else draw Julia Set
        kr = cr
        ki = ci
        kj = cj
        kk = ck
    EndIf
    
    While n < iter
        tem = x+x
        x = x*x-y*y-z*z-w*w+kr
        y = tem*y + ki
        z = tem*z + kj
        w = tem*w + kk
        
        n+1
        distance = x*x+y*y+z*z+w*w
        
        If distance > 4 
          n = iter
        EndIf
        
    Wend
        
    ;Return distance
    ProcedureReturn distance
  
EndProcedure

  

Procedure calcit()
    zz.f
    foo.l
    iterations = 100000
    count = 0
    
    If zval = 0
        zz = 2.0
    Else
        zz = 4.0
    EndIf
      
      For foo = 0 To iterations
          ;x.f = RandF(0, 1)
          ;y.f = RandF(0, 1)
          x.f = RandF(-2, 2)
          y.f = RandF(-2, 2)
          
          z.f = zz*RandF(0, 1) -2.0
          
          ;calls the quaternion calculation
          leng.f = calcleng(x,y,z)
          
          If leng < 4 
              MeshVertexPosition(x, y, z)
              red = (x+Cos(15*leng))*255
              green = (y+Sin(1-leng)*Cos(5*leng))*255
              blue = (z+Sin(0.75*leng))*255
              If red < 0 : red = 0 : EndIf
              If green < 0 : green = 0 : EndIf
              If blue < 0 : blue = 0 : EndIf
              ;If red > 255 : red = red-255 : EndIf
              ;If green > 255 : green = green-255 : EndIf
              ;If blue > 255 : blue = blue-255 : EndIf
              
              ;MeshVertexColor(RGBA(red,green,blue,0))
              MeshVertexColor(RGB(red,green,blue))
              a$=StrF(x)+ "," +StrF(y)+"," +StrF(z)
              WriteStringN(1, a$)
                           
          EndIf
          
        Next 
        NormalizeMesh(1)
        FinishMesh(#True)
              
EndProcedure

OpenFile(1, "dataxyz3.asc")

calcit()  ; calling the mandel 3D or julia generator function
CreateEntity(1, MeshID(1), MaterialID(0))
ScaleEntity(1,2,2,2)
MoveEntity(1,0,1,-2)
;SaveMesh(1, "mandel3D.mesh")
;Main loop
Repeat
  Event = WindowEvent()
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case #BUTTON
        stopFlag ! 1
                    
    EndSelect
  EndIf 
  If stopFlag=1
    x + rotx
    y + roty
    z + rotz
  EndIf
  
   RotateEntity(1, x, y, z)
   
   RenderWorld()
   FlipBuffers()

  ExamineKeyboard()
      
Until KeyboardPushed(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
CloseFile(1)
after that open this file with MeshLab ... read the steps in the above first link.
in the above first link i show how to save as "obj" file. now using the OgreAssimpConverter convert the obj model to *.mesh (OgreAssimpConverter download it from OGRE tools in 3D programming section )
OgreAssimpConverter.exe mandel3d.obj
the mandel3d.mesh does not display shadow so continue
OgreMeshUpgrader.exe mandel3d.mesh to build model edge as explained by Kelebrindae here http://www.purebasic.fr/english/viewtop ... 36&t=52949

the following is just to display the model made by MeshLab from the dataxyz.asc file and converted by OgreAssimpConverter and OgreMeshUpgrader, with physics. the other is the mesh made from SaveMesh which can't have physics and it is made from much more points.
download the two models from here http://www.mediafire.com/?w2rlsurb2kradha and save to the same folder as the following code, also use this gold texture
Image
so you will have this result
Image

Code: Select all

Enumeration
   #MESH = 100
   #TEX
   #TEX_plane
   #MAT
   #MAT_plane
   #plane
   #LIGHT
   #CAMERA
   #BUTTON
   #mainwin
   #mandel
   #mandel2
   #mandel3
EndEnumeration
Global Quit.b = #False

ExamineDesktops()
OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "displaying model made from points", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-50, 0, 0, 0)

WorldShadows(#PB_Shadow_Modulative)
  
EnableWorldPhysics(#True)
EnableWorldCollisions(#True)
SetFrameRate(60)

Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)

CreateMaterial(#MAT_plane, LoadTexture(#TEX_plane, "snow_1024.jpg"))
CreatePlane(#plane, 10, 10, 1, 1, 1, 1)
CreateEntity (#plane, MeshID(#plane), MaterialID(#MAT_plane))
EntityPhysicBody(#plane, #PB_Entity_StaticBody )
SkyDome("clouds.jpg", 80)  
LoadMesh(#MESH, "mandel3d.mesh")
LoadTexture(#TEX, "gold.jpg")
CreateMaterial(#MAT, TextureID(#TEX))
;CreateNode(#mandel)
CreateEntity(#mandel, MeshID(#MESH), MaterialID(#MAT))
;ScaleEntity(#mandel,0.5,0.5,0.5)
MoveEntity(#mandel,-0.5,1.5,3)
EntityRenderMode(#mandel, #PB_Entity_CastShadow)
RotateEntity(#mandel, 0,0,90)
EntityPhysicBody(#mandel, #PB_Entity_StaticBody  ,1,0,1)


CopyEntity(#mandel, #mandel2)
ScaleEntity(#mandel2,0.5,0.5,0.5)
;CreateLight(0,RGB(255,255,255),-100,40,30)
CreateLight(0,RGB(255,255,255),0,40,10)
AmbientColor(RGB(100,100,100))
MoveEntity(#mandel2,0.9 ,5, 3)
EntityPhysicBody(#mandel2, #PB_Entity_ConvexHullBody    ,1,0,0.2)

; create white texture
CreateTexture(7,16,16)
StartDrawing(TextureOutput(7))
Box(0, 0, 16, 16,RGB(255,255,255))
StopDrawing()
CreateMaterial(7, TextureID(7))
DisableMaterialLighting(7, #True)

LoadMesh(#mandel3, "mand3dPoints.mesh")
CreateEntity(#mandel3, MeshID(#mandel3), MaterialID(7))
MoveEntity(#mandel3,3,0.3,-4)
RotateEntity(#mandel3, 0,0,-90)

CreateCamera(#CAMERA, 0, 0, 400, 400)
MoveCamera(#CAMERA, 0, 4, 9)
CameraLookAt(#CAMERA, 0, 2, 0)

RotateCamera(#CAMERA, -15, 0, 0)

;WorldDebug(#PB_World_DebugBody  )
WorldGravity(-2) ; less than normal gravity -9.8
rot.l=1
;Main loop
Repeat
  Event = WindowEvent()
    
  x.f + rot
    
  RotateEntity(#mandel, x, 0, -90)
  RotateEntity(#mandel3, x, 0, -90)
   
   TimeSinceLastFrame = RenderWorld()
   
  FlipBuffers()

   ExamineKeyboard()
   

Until KeyboardReleased(#PB_Key_Escape) Or Event = #PB_Event_CloseWindow

   
    
PS: uncomment line 79 WorldDebug(#PB_World_DebugBody ) to see how much the physics dynamic #PB_Entity_ConvexHullBody are different than #PB_Entity_StaticBody which are exact, while the first are convex
if there is a way to do dynamic concave will be great, usefull for the Gears as an example.

more info:
http://gmv.cast.uark.edu/scanning/point ... n-meshlab/
http://meshlabstuff.blogspot.com/2009/0 ... louds.html
http://en.wikipedia.org/wiki/Point_cloud
http://meshlab.sourceforge.net/