November 30, 2020, 01:44:01 AM

Author Topic: [bb] Export stl by TomToad [ 1+ years ago ]  (Read 572 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Export stl by TomToad [ 1+ years ago ]
« on: June 29, 2017, 12:28:42 AM »
Title : Export stl
Author : TomToad
Posted : 1+ years ago

Description : I needed an .stl exporter for a project I am working on.  I found an importer in the archives, but it did not export, so I wrote one.  To use, just call:
SaveStl(Filename$,Entity,Children)
Filename$ - The name to save the stl file.
Entity - the entity you are saving
Children - True, include children in the file; False, save only the referenced entity.

Example: SaveStl("car.stl",CarEntity,True)

Some notes:
stl has no concept of child or parent entities.  All children are saved as one huge mesh.

stl format allows a file that can contain up to 4,294,967,295 triangles.  Since Blitz3D does not have an unsigned int type, the maximum triangles is only 2,147,483,647

This function currently has no error checking.

stl specifications only allow vertices without negative components. i.e. A vertex should not be -1,0,0.  Most modern software will save/load negative coordinates in an stl file anyway, but is something to keep in mind should you be using software that sticks strictly to the specifications.  Since the function here may save negative coordinates, you need to translate the entities before saving if you are planning on using those programs.

Stl does not use color, nor textures.  They will be stripped from the entity.

Edit 05/22/16:  Oops, forgot to flip the Z axis :)


Code :
Code: BlitzBasic
  1. ;SaveStl() by TomToad
  2. ;
  3. ;Usage
  4. ; SaveStl(Filename$,Entity,Children)
  5. ;
  6. ;       Filename$ - name of the file to be saved
  7. ;       Entity - the entity to be saved
  8. ;       Children - True, all children will be saved in the file; False - Only the referenced entity will be saved
  9.  
  10. ;v1.1 05/22/16 z axis needed to be flipped
  11. ;v1.0 05/22/16 original version
  12. Global SaveStlTrisCount = 0 ;This holds the total number of triangles saved
  13.  
  14. ;Type to hold a 3d vector
  15. Type Vector3D
  16.         Field X#
  17.         Field Y#
  18.         Field z#
  19. End Type
  20.  
  21.  
  22. ;This function saves the actual triangles.  Your program will not call this function.  It is
  23. ;       called by SaveStl() and recursively calls itself for each child entity
  24. Function SaveStlTris(Stream,Entity,Children)
  25.         ; if saving children, then check if the entity has any children.  If no children exist, then
  26.         ; recursively call this function with children set to false, otherwise call this function
  27.         ; for each child entity
  28.         If Children = True Then
  29.                 If CountChildren(Entity) > 0 Then
  30.                         For i = 1 To CountChildren(Entity)
  31.                                 SaveStlTris(Stream,GetChild(Entity,i),True)
  32.                         Next
  33.                 End If
  34.                 SaveStlTris(Stream,Entity,False)
  35.         Else
  36.                 ;Now to save the actual entity.
  37.                 For SurfaceIndex = 1 To CountSurfaces(Entity) ;Go through each surface
  38.                         Surface = GetSurface(Entity,SurfaceIndex)
  39.                         SaveStlTrisCount = SaveStlTrisCount + CountTriangles(Surface) ;Keep track of number of triangles
  40.                         For TriangleIndex = 0 To CountTriangles(Surface)-1 ;go through each triangle on the surface
  41.                                 v0 = TriangleVertex(Surface,TriangleIndex,0) ;get the vertices of the triangle
  42.                                 v1 = TriangleVertex(Surface,TriangleIndex,2) ; vertex 1 and 2 are swapped as stl uses a
  43.                                 v2 = TriangleVertex(Surface,TriangleIndex,1) ; counter-clockwise ordering
  44.                                
  45.                                 ;stl doesn't use scale or rotation, so all the vertices must be transformed to
  46.                                 ; world coordinates
  47.                                 t0.Vector3D = New Vector3d
  48.                                 TFormPoint(VertexX(surface,v0),VertexY(surface,v0),VertexZ(surface,V0),Entity,0)
  49.                                 t0x = TFormedX()
  50.                                 t0y = TFormedY()
  51.                                 t0z = -TFormedZ()
  52.  
  53.                                 t1.Vector3D = New Vector3d
  54.                                 TFormPoint(VertexX(surface,v1),VertexY(surface,v1),VertexZ(surface,V1),Entity,0)
  55.                                 t1x = TFormedX()
  56.                                 t1y = TFormedY()
  57.                                 t1z = -TFormedZ()
  58.                                
  59.                                 t2.Vector3D = New Vector3d
  60.                                 TFormPoint(VertexX(surface,v2),VertexY(surface,v2),VertexZ(surface,V2),Entity,0)
  61.                                 t2x = TFormedX()
  62.                                 t2y = TFormedY()
  63.                                 t2z = -TFormedZ()
  64.                                
  65.                                 ;Now to create the surface normal so that the stl file knows which way is out
  66.                                 U.Vector3D = New Vector3D
  67.                                 V.Vector3D = New Vector3D
  68.                                
  69.                                 Ux = t1x-t0x
  70.                                 Uy = t1y-t0y
  71.                                 Uz = t1z-t0z
  72.                                
  73.                                 Vx = t2x-t0x
  74.                                 Vy = t2y-t0y
  75.                                 Vz = t2z-t0z
  76.                                
  77.                                 Normal.Vector3D = New Vector3D
  78.                                 Normalx = Uy*Vz-Uz*Vy
  79.                                 Normaly = Uz*Vx-Ux*Vz
  80.                                 Normalz = Ux*Vy-Uy*Vx
  81.                                
  82.                                 ;write the normal to the file
  83.                                 WriteFloat(Stream,Normalx)
  84.                                 WriteFloat(Stream,Normaly)
  85.                                 WriteFloat(Stream,Normalz)
  86.                                
  87.                                 ;write the triangle to the file
  88.                                 WriteFloat(Stream,t0x)
  89.                                 WriteFloat(Stream,t0y)
  90.                                 WriteFloat(Stream,t0z)
  91.                                
  92.                                 WriteFloat(Stream,t1x)
  93.                                 WriteFloat(Stream,t1y)
  94.                                 WriteFloat(Stream,t1z)
  95.                                
  96.                                 WriteFloat(Stream,t2x)
  97.                                 WriteFloat(Stream,t2y)
  98.                                 WriteFloat(Stream,t2z)
  99.                                
  100.                                 ;free the types
  101.                                 Delete Normal
  102.                                 Delete U
  103.                                 Delete V
  104.                                 Delete t0
  105.                                 Delete t1
  106.                                 Delete t2
  107.                                
  108.                                 ;attribute count.  set to 0
  109.                                 WriteShort(Stream,0)
  110.                         Next
  111.                 Next
  112.         End If
  113. End Function
  114.  
  115. ;Your program will call this function
  116. ;Filename: Name of the file to be saved
  117. ;Entity: Parent entity to be saved
  118. ;Children: True to aslo save child entities, false to only save parent
  119.  
  120. Function SaveStl(Filename$,Entity,Children)
  121.         SaveStlTrisCount = 0 ;reset the triangle count to 0
  122.         Stream = WriteFile(Filename)
  123.         For i = 1 To 21 ;80 byte header + triangle count
  124.                 WriteInt(Stream,0)
  125.         Next
  126.        
  127.         SaveStlTris(Stream,Entity,Children) ;save the triangles
  128.         current = FilePos(Stream) ;save the current stream position
  129.         SeekFile(Stream,80) ;move to the triangle count positon
  130.         WriteInt(Stream,SaveStlTrisCount) ;write the number of triangles saved
  131.         CloseFile Stream
  132. End Function
  133.  
  134. ;--------------------------------------------
  135. ;
  136. ;  The code below is a sample of using the
  137. ;     Function SaveStl()
  138. ;
  139. ;---------------------------------------------
  140.  
  141. Graphics3D 800,600
  142.  
  143. cube = CreateCube() ;create a cube
  144. sphere = CreateSphere(8,Cube) ;create a sphere, make cube its parent
  145. ScaleEntity sphere,2,2,2 ;scale and move the sphere
  146. PositionEntity sphere,5,0,0
  147.  
  148. SaveStl("cube.stl",Cube,False) ;save the cube, but not its children
  149.  
  150. SaveStl("sphere.stl",sphere,False) ;save the sphere
  151.  
  152. SaveStl("all.stl",Cube,True) ;save the cube and all its children
  153.  
  154.  
  155. camera = CreateCamera()
  156. PositionEntity camera,0,0,-10
  157.  
  158. light = CreateLight()
  159. RotateEntity light,45,45,45
  160.  
  161. While Not KeyHit(1)
  162.         Cls
  163.        
  164.         UpdateWorld
  165.         RenderWorld
  166.         Flip
  167.         If KeyDown(17) ;w
  168.                 MoveEntity camera,0,0,.2
  169.         End If
  170.         If KeyDown(31) ;s
  171.                 MoveEntity camera,0,0,-.2
  172.         End If
  173.         If KeyDown(30) ;a
  174.                 TurnEntity camera,0,-1,0
  175.         End If
  176.         If KeyDown(32) ;d
  177.                 TurnEntity camera,0,1,0
  178.         End If
  179. Wend


Comments :


Blitzplotter(Posted 1+ years ago)

 interesting code


Blitzplotter(Posted 1 day ago)

 Just got around to testing this Tom Toad, great work.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal