stl to egg script

Hello all, I’m starting work on an application where a user can load an STL file and can view/translate it. Panda3d seems like a great candidate for the application but I need help understanding the egg format and how panda loads models. I am quite new to python but seem to be able to pick through, understand and modify code fairly easily. My first goal is to display an open dialog to user who then would select an STL file and it will then be loaded into view. I know I will have to write a script to translate on the fly from STL. This seems like it should be fairly straight forward. There are two formats for STL Binary and ASCII, if I could get at least the ASCII format to load that would be awesome.

http://en.wikipedia.org/wiki/STL_%28file_format%29
Here’s an ASCII STL for a simple cube:

solid block10
   facet normal 0 0 0
      outer loop
         vertex 0 10 10
         vertex 0 10 0
         vertex 0 0 10
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 0 0 10
         vertex 0 10 0
         vertex 0 0 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 10 10
         vertex 0 10 10
         vertex 10 0 10
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 0 10
         vertex 0 10 10
         vertex 0 0 10
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 10 0
         vertex 10 10 10
         vertex 10 0 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 0 0
         vertex 10 10 10
         vertex 10 0 10
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 0 10 0
         vertex 10 10 0
         vertex 0 0 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 0 0 0
         vertex 10 10 0
         vertex 10 0 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 10 10
         vertex 10 10 0
         vertex 0 10 10
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 0 10 10
         vertex 10 10 0
         vertex 0 10 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 10 0 0
         vertex 10 0 10
         vertex 0 0 0
      endloop
   endfacet
   facet normal 0 0 0
      outer loop
         vertex 0 0 0
         vertex 10 0 10
         vertex 0 0 10
      endloop
   endfacet
endsolid

Hints or tips on loading into panda would me much appreciated!

Look at Section Q in the Manual, “Procedurally Generating 3D Models”.


panda3d.org/manual/index.php/Main_Page

Thanks for that , although its a bit over my head as of now. :wink:

For selecting a file I’d use wxWidgets. There are threads around here that show how to use it. Alternatively read the file as argument on the command line.

And for generating the actual geometry you can either convert it to egg or x (might be easier, idk), or generate the geometry through code as suggested above.

Adding wxPython just for a file browser might not be worth it, Tk has an easy way of using the OS’s default file browser itself:

from Tkinter import Tk
from tkFileDialog import askopenfilename

root = Tk()
root.withdraw() # Panda already created a window

filename = askopenfilename(filetypes = [('all files','*'), ('STL models','*.stl')])

Thanks for the help guys i’ll start working on this tomorrow. I will have more questions no doubt, But it seems I have enough to get started.

oh wait I got one now :laughing:

Not sure if I should start a new thread for this, but maybe someone has some experience in procedurally generating a grid plane?

This usually is a good beginning: panda3d.org/reference/devel … ctGrid.php

It’s a python class, by the way.

Hello,

I made a small piece of code which would be usefull (I hope). It simply parse an ASCII STL file, reading the “vertex” instructions.

It’s made with two part :
– a description of 3D points, vectors and vertex.
– a simple stl parser.
As you are using panda3D engine, you can scratch the first part.

def3D.py --> http://codepad.org/y9Gs62dL
main.py --> http://codepad.org/rXWgSTID

I’ll try to use 'Procedural Generating" : must be fun ![/url]
[/code]

DirectGrid crashes in 1.8, you need to modify few things.

# taken from direct/directtool
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject
from direct.directtools.DirectUtil import *
from direct.directtools.DirectGeometry import *

class DirectGrid(NodePath, DirectObject):
    def __init__(self,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5),parent = None):
        # Initialize superclass
        NodePath.__init__(self, 'DirectGrid')
        # Don't wireframe or light
        useDirectRenderStyle(self)

        # Load up grid parts to initialize grid object
        # Polygon used to mark grid plane
        self.gridBack = loader.loadModel('models/misc/gridBack')
        self.gridBack.reparentTo(self)
        self.gridBack.setColor(*planeColor)

        # Grid Lines
        self.lines = self.attachNewNode('gridLines')
        self.minorLines = LineNodePath(self.lines)
        self.minorLines.lineNode.setName('minorLines')
        self.minorLines.setColor(VBase4(0.3, 0.55, 1, 1))
        self.minorLines.setThickness(1)

        self.majorLines = LineNodePath(self.lines)
        self.majorLines.lineNode.setName('majorLines')
        self.majorLines.setColor(VBase4(0.3, 0.55, 1, 1))
        self.majorLines.setThickness(5)

        self.centerLines = LineNodePath(self.lines)
        self.centerLines.lineNode.setName('centerLines')
        self.centerLines.setColor(VBase4(1, 0, 0, 0))
        self.centerLines.setThickness(3)

        # Small marker to hilight snap-to-grid point
        self.snapMarker = loader.loadModel('models/misc/sphere')
        self.snapMarker.node().setName('gridSnapMarker')
        self.snapMarker.reparentTo(self)
        self.snapMarker.setColor(1, 0, 0, 1)
        self.snapMarker.setScale(0.3)
        self.snapPos = Point3(0)

        # Initialize Grid characteristics
        self.fXyzSnap = 1
        self.fHprSnap = 1
        self.gridSize = gridSize
        self.gridSpacing = gridSpacing
        self.snapAngle = 15.0
        self.enable(parent = parent)

    def enable(self, parent = render):
        self.reparentTo(render)
          
        self.updateGrid()
        self.fEnabled = 1

    def disable(self):
        self.detachNode()
        self.fEnabled = 0

    def toggleGrid(self, parent = render):
        if self.fEnabled:
            self.disable()
        else:
            self.enable(parent = parent)

    def isEnabled(self):
        return self.fEnabled

    def updateGrid(self):
        # Update grid lines based upon current grid spacing and grid size
        # First reset existing grid lines
        self.minorLines.reset()
        self.majorLines.reset()
        self.centerLines.reset()

        # Now redraw lines
        numLines = int(math.ceil(self.gridSize/self.gridSpacing))
        scaledSize = numLines * self.gridSpacing

        center = self.centerLines
        minor = self.minorLines
        major = self.majorLines
        for i in range(-numLines, numLines + 1):
            if i == 0:
                center.moveTo(i * self.gridSpacing, -scaledSize, 0)
                center.drawTo(i * self.gridSpacing, scaledSize, 0)
                center.moveTo(-scaledSize, i * self.gridSpacing, 0)
                center.drawTo(scaledSize, i * self.gridSpacing, 0)
            else:
                if (i % 5) == 0:
                    major.moveTo(i * self.gridSpacing, -scaledSize, 0)
                    major.drawTo(i * self.gridSpacing, scaledSize, 0)
                    major.moveTo(-scaledSize, i * self.gridSpacing, 0)
                    major.drawTo(scaledSize, i * self.gridSpacing, 0)
                else:
                    minor.moveTo(i * self.gridSpacing, -scaledSize, 0)
                    minor.drawTo(i * self.gridSpacing, scaledSize, 0)
                    minor.moveTo(-scaledSize, i * self.gridSpacing, 0)
                    minor.drawTo(scaledSize, i * self.gridSpacing, 0)

        center.create()
        minor.create()
        major.create()
        if (self.gridBack):
            self.gridBack.setScale(scaledSize)

    def setXyzSnap(self, fSnap):
        self.fXyzSnap = fSnap

    def getXyzSnap(self):
        return self.fXyzSnap

    def setHprSnap(self, fSnap):
        self.fHprSnap = fSnap

    def getHprSnap(self):
        return self.fHprSnap

    def computeSnapPoint(self, point):
        # Start of with current point
        self.snapPos.assign(point)
        # Snap if necessary
        if self.fXyzSnap:
            self.snapPos.set(
                ROUND_TO(self.snapPos[0], self.gridSpacing),
                ROUND_TO(self.snapPos[1], self.gridSpacing),
                ROUND_TO(self.snapPos[2], self.gridSpacing))

        # Move snap marker to this point
        self.snapMarker.setPos(self.snapPos)

        # Return the hit point
        return self.snapPos

    def computeSnapAngle(self, angle):
        return ROUND_TO(angle, self.snapAngle)

    def setSnapAngle(self, angle):
        self.snapAngle = angle

    def getSnapAngle(self):
        return self.snapAngle

    def setGridSpacing(self, spacing):
        self.gridSpacing = spacing
        self.updateGrid()

    def getGridSpacing(self):
        return self.gridSpacing

    def setGridSize(self, size):
        # Set size of grid back and redraw lines
        self.gridSize = size
        self.updateGrid()

    def getGridSize(self):
        return self.gridSize

Hey I got this to work but there was a syntax error on line 33 in def3D.py. I replaced curly brackets with square ones works good! I want to try to do it from scratch my self for learning purposes. Thanks a lot! I can see I definitely need to work on my python skills. A lot of this still overwhelming :wink: but still good practice. I’ll post my script when i get it!

Also i just found this probably should have searched a bit more earlier!
https://discourse.panda3d.org/viewtopic.php?p=86836#86836
Lost of code to learn from here thanks soo much guys very helpful.

I used panda3d eggXXXXX functions to create the .egg file
You can load both ASCII and Bin STL file.
usage :
ppython stl2egg.py infile.stl outfile.egg [–show]

The --show is optional
http://codepad.org/5fQUyacE

Hi, I just discovered this topic as i’m going to use .stl files with Panda3d Studio, and i found out that the script of @raoullevert doesn’t work anymore, so i updated it.

Here’s the working code

I’m going to create a code for converting .egg files to .stl too, but idk when it will be ready

Edit: actually the option “–show” doesn’t work for me because of an OpenGL error, even if the program does the convertion without problems, let me know if it works for you or if you have a solution