POV-Ray : Newsgroups : povray.general : Impossible stl file conversion! Server Time
15 Sep 2025 08:19:32 EDT (-0400)
  Impossible stl file conversion! (Message 9 to 18 of 18)  
<<< Previous 8 Messages Goto Initial 10 Messages
From: kurtz le pirate
Subject: Re: Impossible stl file conversion!
Date: 10 Sep 2025 11:11:36
Message: <68c19528@news.povray.org>
On 10/09/2025 16:23, ingo wrote:

> 
> A conversion script in a scripting lang is the way out.
> 


I agree with you.


The wiki page shows that the structure is very simple, and I think Perl* 
is a very good candidate for this.




* : (from WIKIPEDIA) Perl was developed by Larry Wall in 1987 and STL 
was invented by the Albert Consulting Group for 3D Systems in 1987 too LOL



-- 
kurtz le pirate
compagnie de la banquise


Post a reply to this message

From: ingo
Subject: Re: Impossible stl file conversion!
Date: 10 Sep 2025 11:25:00
Message: <web.68c1979ca068c28c17bac71e8ffb8ce3@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> I mean, yeah - I just hate all the extra steps, and the generation of a whole
> new file that takes up space next to the original stl.

for the current POV-Ray situation, I'm mostly writing my own little tools "that
do things" and then call POV-Ray on the generated scene. The opposite of POV-Ray
should be able to do it "all". Although I would like the latter,

ingo


Post a reply to this message

From: Bald Eagle
Subject: Re: Impossible stl file conversion!
Date: 10 Sep 2025 12:55:00
Message: <web.68c1ac45a068c28cbe3debd925979125@news.povray.org>
"ingo" <nomail@nomail> wrote:

> for the current POV-Ray situation, I'm mostly writing my own little tools "that
> do things" and then call POV-Ray on the generated scene. The opposite of POV-Ray
> should be able to do it "all". Although I would like the latter,
>
> ingo

Well, given "the current POV-Ray situation", I'm trying to break out of that,
since "what is tolerated is what will continue".
I suppose I have a Persistence of Vision.  ;)

I'm not exclusionarily averse to things like macros and separate utilities,
however, it would be highly desireable to in some way integrate those things
into the POV-Ray "package".

An official repository on the website, a folder in the official distro, scripts
to run whatever conversion or creation needs to be done, or most preferable -
the inclusion of an additional module in the source.

I'm especially pushing for this stl module, since it appears so straightforward
a task (for a c++ programmer), and the availability of millions of free stl
files available.  We don't have a modeler - but there are models.

And it there are modelers available to make/edit stls.....

- BW


Post a reply to this message

From: ingo
Subject: Re: Impossible stl file conversion!
Date: 11 Sep 2025 04:05:00
Message: <web.68c28199a068c28c17bac71e8ffb8ce3@news.povray.org>
"Bald Eagle" <cre### [at] netscapenet> wrote:

> #declare MyObject = mesh2 {stl "MyObject.stl" make_arrays ...}

#declare MyStlObject = mesh2{stl "MyObject.stl"}
#declare MyObjObject = mesh2{obj "MyObject.obj"}

that's quite elegant, to extract from a file format, what POV-Ray understands
based on mesh2.

I'd separate extracting array into something like:

mesh2array(mySTLObject, verticesname, normalsname, facesname, uvname,
vertexcoulours etc..)

could result in a bunch of arrays declared with the given names. It should take
mesh & mesh2.

and/or

mesharrays{obj "MyObjObject.obj"} and extract everything the file supports into
arrays, even what's not understood by mesh2, like boning, face normals or non
triangle faces.


ingo


Post a reply to this message

From: yesbird
Subject: Re: Impossible stl file conversion!
Date: 11 Sep 2025 06:20:18
Message: <68c2a262$1@news.povray.org>
On 09/09/2025 02:32, Bald Eagle wrote:
>                   ........... what's that?!!!
> 
> He provides not one but TWO .stl files . . .
> 

Blender can import STL and export POV.
-- 
YB


Post a reply to this message

From: kurtz le pirate
Subject: Re: Impossible stl file conversion!
Date: 11 Sep 2025 10:51:10
Message: <68c2e1de@news.povray.org>
On 10/09/2025 17:11, kurtz le pirate wrote:
> 
> The wiki page shows that the structure is very simple, and I think Perl* 
> is a very good candidate for this.
> 


Finally, I spent an hour and here is my first result ;)


I found this template on the web : 
<https://www.thingiverse.com/thing:7119375>. The downloaded STL file is 
in binary mode. I converted it to ASCII on this website : 
<https://3dcustomizer.net/tests/stl-bin-to-ascii.html>

Here is the first image to compare with the one on Thingiverse.


I also added an archive that contains :

* Stackable_crate_gridfinity-ascii.stl : the ascii stl file

* stl2pov.pl : the perl script

* Stackable_crate_gridfinity-ascii.inc : the mesh{} include file
   generated by the script

* test.pov : demo scene

* test.png : the image





Of course, there are quite a few things to add such as binary format, 
normals & mesh2{}, colors, etc.


-- 
kurtz le pirate
compagnie de la banquise


Post a reply to this message


Attachments:
Download 'test.png' (376 KB) Download 'stl2pov.tar.gz' (1239 KB)

Preview of image 'test.png'
test.png

From: kurtz le pirate
Subject: Re: Impossible stl file conversion!
Date: 11 Sep 2025 12:55:20
Message: <68c2fef8@news.povray.org>
On 11/09/2025 16:51, kurtz le pirate wrote:
> 
> Of course, there are quite a few things to add such as binary format, 
> normals & mesh2{}, colors, etc.
> 

Three more attempts always from Thingiverse.
The lack of normals is clearly visible :(







-- 
kurtz le pirate
compagnie de la banquise


Post a reply to this message


Attachments:
Download 'aat.low.jpeg.jpg' (75 KB) Download 'fish.low.jpeg.jpg' (80 KB) Download 'lamp.low.jpeg.jpg' (65 KB)

Preview of image 'aat.low.jpeg.jpg'
aat.low.jpeg.jpg

Preview of image 'fish.low.jpeg.jpg'
fish.low.jpeg.jpg

Preview of image 'lamp.low.jpeg.jpg'
lamp.low.jpeg.jpg


 

From: ingo
Subject: Re: Impossible stl file conversion!
Date: 11 Sep 2025 14:30:00
Message: <web.68c31440a068c28c17bac71e8ffb8ce3@news.povray.org>
A quicky in Nim, not much tested:

---%<------%<------%<------%<---

#asciistl2pov.nim

import std/[math, sequtils, strformat, strutils]

type
  Vec3 = array[3, float]
  Face = array[3, int]

proc vec3(x,y,z: float): Vec3 = [x,y,z]

proc `+`(a,b: Vec3): Vec3 = [a[0]+b[0], a[1]+b[1], a[2]+b[2]]

proc `/`(a: Vec3, s: float): Vec3 = [a[0]/s, a[1]/s, a[2]/s]

proc dot(a,b: Vec3): float = a[0]*b[0]+a[1]*b[1]+a[2]*b[2]

proc length(v: Vec3): float = sqrt(dot(v,v))

proc normalize(v: Vec3): Vec3 =
  let l = length(v)
  if l > 1e-9: v / l else: vec3(0,1,0)


# Load STL, ASCII only
proc loadSTL(path: string): (seq[Vec3], seq[Face], seq[Vec3]) =
  var verts: seq[Vec3] = @[]
  var faces: seq[Face] = @[]
  var norms: seq[Vec3] = @[]
  var curVerts: seq[int] = @[]
  var curNormal = vec3(0,0,0)
  for line in lines(path):
    let l = line.strip()
    if l.startsWith("facet normal"):
      let p = l.splitWhitespace()
      curNormal = vec3(p[2].parseFloat, p[3].parseFloat, p[4].parseFloat)
    elif l.startsWith("vertex"):
      let p = l.splitWhitespace()
      let v = vec3(p[1].parseFloat, p[2].parseFloat, p[3].parseFloat)
      verts.add(v)
      curVerts.add(verts.len-1)
    elif l.startsWith("endfacet"):
      if curVerts.len == 3:
        faces.add([curVerts[0], curVerts[1], curVerts[2]])
        norms.add(curNormal)
      curVerts.setLen(0)
  return (verts, faces, norms)


proc vertexToFaces(faces: seq[Face], vertexCount: int): seq[seq[int]] =
  result = newSeqWith(vertexCount, newSeq[int]())
  for fIdx, f in faces:
    for vi in f:
      result[vi].add(fIdx)


proc computeVertexNormals(
  vertexCount: int, faceNormals: seq[Vec3], v2f: seq[seq[int]]
): seq[Vec3] =
  result = newSeqWith(vertexCount, vec3(0,0,0))
  for vIdx in 0..<vertexCount:
    var accum = vec3(0,0,0)
    for fIdx in v2f[vIdx]:
      accum = accum + faceNormals[fIdx]
    result[vIdx] = normalize(accum)


proc mesh2ToString(
  verts: seq[Vec3], faces: seq[Face], normals: seq[Vec3]
): string =
  var sb = newStringOfCap(verts.len * 100) # Preallocate rough size
  sb.add("#declare MSH = mesh2 {\n")

  # Vertex vectors
  sb.add("  vertex_vectors {\n")
  sb.add("    " & $verts.len & ",\n")
  for v in verts:
    sb.add(&"    <{v[0]}, {v[1]}, {v[2]}>,\n")
  sb.add("  }\n")

  # Normal vectors
  sb.add("  normal_vectors {\n")
  sb.add("    " & $normals.len & ",\n")
  for n in normals:
    sb.add(&"    <{n[0]}, {n[1]}, {n[2]}>,\n")
  sb.add("  }\n")

  # Face indices
  sb.add("  face_indices {\n")
  sb.add("    " & $faces.len & ",\n")
  for f in faces:
    sb.add(&"    <{f[0]}, {f[1]}, {f[2]}>,\n")
  sb.add("  }\n")

  sb.add("}\n")
  result = sb


proc writeMesh2(outPath: string, verts: seq[Vec3], faces: seq[Face], normals:
seq[Vec3]) =
  let s = mesh2ToString(verts, faces, normals)
  writeFile(outPath, s)


when isMainModule:
  let (verts, faces, faceNorms) = loadSTL("mesh_output.stl")
  let v2f = vertexToFaces(faces, verts.len)
  let vertexNorms = computeVertexNormals(verts.len, faceNorms, v2f)
  writeMesh2("model.inc", verts, faces, vertexNorms)
  echo "Converted STL to POV-Ray mesh2 with normals."

---%<------%<------%<------%<---

ingo


Post a reply to this message

From: kurtz le pirate
Subject: Re: Impossible stl file conversion!
Date: 12 Sep 2025 13:07:20
Message: <68c45348@news.povray.org>
On 11/09/2025 20:26, ingo wrote:
> A quicky in Nim, not much tested:
> 
> ---%<------%<------%<------%<---
> 
> [snip]
> 
> ---%<------%<------%<------%<---
> 
> ingo


I don't know Nim very well, but the code is interesting.
Even Yoda agrees ;)





-- 
kurtz le pirate
compagnie de la banquise


Post a reply to this message


Attachments:
Download 'test_yoda.jpeg.jpg' (233 KB)

Preview of image 'test_yoda.jpeg.jpg'
test_yoda.jpeg.jpg


 

From: ingo
Subject: Re: Impossible stl file conversion!
Date: 12 Sep 2025 14:10:00
Message: <web.68c46188a068c28c17bac71e8ffb8ce3@news.povray.org>
kurtz le pirate <kur### [at] freefr> wrote:
>
>
> I don't know Nim very well, but the code is interesting.
> Even Yoda agrees ;)


Hahaha. Well, for Yoda then, one that reads binary stl, rather untested again,

---%<------%<------%<------%<---
import std/[streams,math, sequtils, strformat]

type
  Vec3 = array[3, float]
  Face = array[3, int]

proc vec3(x,y,z: float): Vec3 = [x,y,z]
proc `+`(a,b: Vec3): Vec3 = [a[0]+b[0], a[1]+b[1], a[2]+b[2]]
proc `/`(a: Vec3, s: float): Vec3 = [a[0]/s, a[1]/s, a[2]/s]
proc dot(a,b: Vec3): float = a[0]*b[0]+a[1]*b[1]+a[2]*b[2]
proc length(v: Vec3): float = sqrt(dot(v,v))
proc normalize(v: Vec3): Vec3 =
  let l = length(v)
  if l > 1e-9: v / l else: vec3(0,1,0)

proc readVec3(s: Stream): Vec3 =
  result[0] = s.readFloat32()
  result[1] = s.readFloat32()
  result[2] = s.readFloat32()

proc loadBinarySTL(path: string): (seq[Vec3], seq[Face], seq[Vec3]) =
  ## Parse binary STL, returning vertices, faces, and per-face normals
  var f = newFileStream(path, fmRead)
  defer: f.close()
  discard f.readStr(80)           # skip header
  let triCount = f.readUint32()

  var verts: seq[Vec3] = @[]
  var faces: seq[Face] = @[]
  var faceNorms: seq[Vec3] = @[]

  for i in 0..<int(triCount):
    let n = readVec3(f)           # face normal
    let v1 = readVec3(f)
    let v2 = readVec3(f)
    let v3 = readVec3(f)
    discard f.readUint16()        # attribute byte count

    let base = verts.len
    verts.add(v1)
    verts.add(v2)
    verts.add(v3)
    faces.add([base, base+1, base+2])
    faceNorms.add(normalize(n))

  return (verts, faces, faceNorms)

# adjecent vertises
proc vertexToFaces(faces: seq[Face], vertexCount: int): seq[seq[int]] =
  result = newSeqWith(vertexCount, newSeq[int]())
  for fi, f in faces:
    for vi in f:
      result[vi].add(fi)

# Vertex normals by averaging face normals
proc computeVertexNormals(vertexCount: int, faceNormals: seq[Vec3], v2f:
seq[seq[int]]): seq[Vec3] =
  result = newSeqWith(vertexCount, vec3(0,0,0))
  for vi in 0..<vertexCount:
    var accum = vec3(0,0,0)
    for fi in v2f[vi]:
      accum = accum + faceNormals[fi]
    result[vi] = normalize(accum)

proc mesh2ToString(verts: seq[Vec3], faces: seq[Face], normals: seq[Vec3]):
string =
  var sb = newStringOfCap(verts.len * 100)
  sb.add("mesh2 {\n")
  sb.add("  vertex_vectors {\n")
  sb.add("    " & $verts.len & ",\n")
  for v in verts: sb.add(&"    <{v[0]}, {v[1]}, {v[2]}>,\n")
  sb.add("  }\n")
  sb.add("  normal_vectors {\n")
  sb.add("    " & $normals.len & ",\n")
  for n in normals: sb.add(&"    <{n[0]}, {n[1]}, {n[2]}>,\n")
  sb.add("  }\n")
  sb.add("  face_indices {\n")
  sb.add("    " & $faces.len & ",\n")
  for f in faces: sb.add(&"    <{f[0]}, {f[1]}, {f[2]}>,\n")
  sb.add("  }\n")
  sb.add("}\n")
  result = sb

proc writeMesh2(path: string, verts: seq[Vec3], faces: seq[Face], normals:
seq[Vec3]) =
  writeFile(path, mesh2ToString(verts, faces, normals))

when isMainModule:
  let (verts, faces, faceNorms) = loadBinarySTL("model.stl")
  let v2f = vertexToFaces(faces, verts.len)
  let vertexNorms = computeVertexNormals(verts.len, faceNorms, v2f)
  writeMesh2("model.inc", verts, faces, vertexNorms)
  echo "Binary STL converted to POV-Ray mesh2."

---%<------%<------%<------%<---

They realy should have/get a decent command line interface...

ingo


Post a reply to this message

<<< Previous 8 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.