POV-Ray : Newsgroups : povray.advanced-users : Mesh replacements for primitives? Server Time
16 Apr 2024 13:18:54 EDT (-0400)
  Mesh replacements for primitives? (Message 1 to 5 of 5)  
From: Bald Eagle
Subject: Mesh replacements for primitives?
Date: 6 Aug 2016 20:30:06
Message: <web.57a68052fcf2bee95e7df57c0@news.povray.org>
Has anyone ever made, or thought of making a library of mesh objects to
approximate some of POV-Ray's primitives?

I just ran a scene that employed 8 million spheres, and that ate up 11 GIGAbytes
of memory.  (I'm glad I recently shoved 16 GB into this thing) :O

Finite Objects:      8026445
Peak memory used:       11 487 420 416 bytes

As I understand it, I can declare a mesh object once, and then just translate
instances of it, which doesn't take up any, or very much more memory.

I'd be interested in learning how, and helping to generate a library of macros
for parameterized mesh objects, so that one could simply add

object {Sphere( <X, Y, Z>, Radius) etc... }

to a scene, and have it substantially perform the same function as a sphere in
most scenes using spheres.

Does this sound like a good idea?  Worthwhile?

I can easily see myself using 16 or 32 million of such objects, if not more.


Post a reply to this message

From: clipka
Subject: Re: Mesh replacements for primitives?
Date: 6 Aug 2016 21:33:56
Message: <57a69004$1@news.povray.org>
Am 07.08.2016 um 02:26 schrieb Bald Eagle:

> I just ran a scene that employed 8 million spheres, and that ate up 11 GIGAbytes
> of memory.  (I'm glad I recently shoved 16 GB into this thing) :O
> 
> Finite Objects:      8026445
> Peak memory used:       11 487 420 416 bytes
> 
> As I understand it, I can declare a mesh object once, and then just translate
> instances of it, which doesn't take up any, or very much more memory.

I'm sorry to disappoint you, but using meshes won't give you as much of
an advantage in terms of memory as you might expect.

While creating multiple instances of a mesh does indeed typically add
only little memory overhead compared to the mesh data itself, that
overhead is still in the same ballpark as that for a single sphere.

(It may also be worthwhile noting that the "Finite Objects:" entry in
the parser summary only specifies the number of finite obects at the top
level of the scene. This does include objects in pure unions (as the
parser will pull them out into the top level), but not in other CSG
constructs.)


That said, I've just identified a block of 256 bytes allocated for each
and every sphere that is translated, rotated, scaled or otherwise
transformed, which I might be able to get rid of.


Post a reply to this message

From: architype
Subject: Re: Mesh replacements for primitives?
Date: 7 Aug 2016 12:40:01
Message: <web.57a7638bdb2c4731bd10344a0@news.povray.org>
>Has anyone ever made, or thought of making a library of mesh objects to
>approximate some of POV-Ray's primitives?

>As I understand it, I can declare a mesh object once, and then just translate
>instances of it, which doesn't take up any, or very much more memory.

>I'd be interested in learning how, and helping to generate a library of macros
>for parameterized mesh objects, so that one could simply add

>Does this sound like a good idea?  Worthwhile?

It is a good idea, and I have done some things in line with that.
But the crux here is not to replace a single sphere with a single
mesh.
The idea is to create a _set of multiple spheres_ as _a single mesh_
and break the whole scene into such complex meshes.

The sphere is a bad example because it is too complex for demo purposes.

But imagine that you are making a large office building that is fitted
out with the same kind of furniture on every floor. (I dunno, a hotel?)

For simplicity we assume that the there is only one type of chair and
one type of table, conviniently made up of boxes... :p

So then we create the object using this type of call:

#local bW = 1;
#local bH = 1;
#local bT = 1;

#local bX0 = 0;
#local bY0 = 0;
#local bZ0 = 0;

#include "blah blah search path blah \ Mesh.tch"

and in mesh.tch the code is:

____________________________________________________________________________________________

#local trn = <bX0, bY0, bZ0>;

#local BtmP1 = < bW/2, 0,  bT/2>+trn;
#local BtmP2 = <-bW/2, 0,  bT/2>+trn;
#local BtmP3 = <-bW/2, 0, -bT/2>+trn;
#local BtmP4 = < bW/2, 0, -bT/2>+trn;

#local TopP1 = < bW/2, bH,  bT/2>+trn;
#local TopP2 = <-bW/2, bH,  bT/2>+trn;
#local TopP3 = <-bW/2, bH, -bT/2>+trn;
#local TopP4 = < bW/2, bH, -bT/2>+trn;


      // btm
      triangle{ BtmP1, BtmP2, BtmP3 }
      triangle{ BtmP1, BtmP4, BtmP3 }
      // top
      triangle{ TopP1, TopP2, TopP3 }
      triangle{ TopP1, TopP4, TopP3 }

      // front
      triangle{ BtmP1, BtmP2, TopP2 }
      triangle{ TopP1, TopP2, BtmP1 }
      // back
      triangle{ BtmP3, BtmP4, TopP4 }
      triangle{ TopP3, TopP4, BtmP3 }

      // left
      triangle{ BtmP2, BtmP3, TopP3 }
      triangle{ TopP2, TopP3, BtmP2 }
      // right
      triangle{ BtmP1, BtmP4, TopP4 }
      triangle{ TopP1, TopP4, BtmP1 }

____________________________________________________________________________________________

the chair is created by something like:
#local ChairObj =
mesh{

// leg 01
#local bW = .1;
#local bH = 1;
#local bT = .1;

#local bX0 = 0.5;
#local bY0 = 0;
#local bZ0 = 0.5;

#include "blah blah search path blah \ Mesh.tch"

// leg 02
#local bW = .1;
#local bH = 1;
#local bT = .1;

#local bX0 = -0.5;
#local bY0 = 0;
#local bZ0 = 0.5;

#include "blah blah search path blah \ Mesh.tch"

blah blah two more legs


// seat
#local bW = 1;
#local bH = .1;
#local bT = 1;

#local bX0 = 0;
#local bY0 = 1;
#local bZ0 = 0;

#include "blah blah search path blah \ Mesh.tch"

// back support
#local bW = .5;
#local bH = .5;
#local bT = .1;

#local bX0 = 0.5;
#local bY0 = 1;
#local bZ0 = 0;

#include "blah blah search path blah \ Mesh.tch"


} // end mesh

So if the chair consists of 4 legs, 1 seat and one back support, you have have
saved 5 objects and the scene will now have x/6 objects.
The table is done in the same way, and one could probably make table group with
chairs and a table as single mesh.

I have also made a box that is rotatable:
(you cannot use rotate or translate on the triangles inside the mesh, at least
not when I wrote the code)

// LOAD ONCE
#include "blah blah\MeshPntTrn.Inc"


// BOX PARAM
#local bW = 1;
#local bH = 4;
#local bT = 1;

#local Init_Trn = <0, 0, 0>;

// ANGLE PARAM
#local aX = 60;
#local aY = 0;
#local aZ = 0;

// TRN PARAM
#local Place_Trn = <0, 0, 0>;


#include "blah blah\ROT_TRN.tch"


___________________________________________________________________________________________________________
MeshPntTrn.Inc

#macro ROT_X(p, aP)

        #if(p.y = 0)
                #if (p.z=0)
                        #local a0 = 0;
                #else
                        #local a0 = atan2d(p.z, p.y);
                #end
        #else
                #local a0 = atan2d(p.z, p.y);
        #end

        #local p = <p.x, sqrt(p.y*p.y + p.z*p.z)*cos(-(a0+aP)*pi/180),
sqrt(p.y*p.y + p.z*p.z)*sin((a0+aP)*pi/180)>;
        //#local p = <sqrt(p.y*p.y + p.z*p.z)*cos(-(a0+aP)*pi/180), p.y,
sqrt(p.y*p.y + p.z*p.z)*sin(-(a0+aP)*pi/180)>;

#end


#macro ROT_Y(p, aP)

        #if(p.x = 0)
                #if (p.z=0)
                        #local a0 = 0;
                #else
                        #local a0 = atan2d(p.z, p.x);
                #end
        #else
                #local a0 = atan2d(p.z, p.x);
        #end

        #local p = <sqrt(p.x*p.x + p.z*p.z)*cos(-(a0+aP)*pi/180), p.y,
sqrt(p.x*p.x + p.z*p.z)*sin(-(a0+aP)*pi/180)>;

#end


#macro ROT_Z(p, aP)

        #if(p.x = 0)
                #if (p.y=0)
                        #local a0 = 0;
                #else
                        #local a0 = atan2d(p.y, p.x);
                #end
        #else
                #local a0 = atan2d(p.y, p.x);
        #end

        #local p = <sqrt(p.x*p.x + p.y*p.y)*cos(-(a0+aP)*pi/180), sqrt(p.x*p.x +
p.y*p.y)*sin((a0+aP)*pi/180), p.z>;

#end


#macro TRN(p, PT)

        #local p = <p.x+PT.x, p.y+PT.y, p.z+PT.z>;

#end

___________________________________________________________________________________________________________

ROT_TRN.tch

        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        // ASSIGN VALUES, implementation


        #local BtmP1 = < bW/2, 0,  bT/2> + Init_Trn;
        #local BtmP2 = <-bW/2, 0,  bT/2> + Init_Trn;
        #local BtmP3 = <-bW/2, 0, -bT/2> + Init_Trn;
        #local BtmP4 = < bW/2, 0, -bT/2> + Init_Trn;

        #local TopP1 = < bW/2, bH,  bT/2> + Init_Trn;
        #local TopP2 = <-bW/2, bH,  bT/2> + Init_Trn;
        #local TopP3 = <-bW/2, bH, -bT/2> + Init_Trn;
        #local TopP4 = < bW/2, bH, -bT/2> + Init_Trn;




        ROT_X(BtmP1, aX);
        ROT_X(BtmP2, aX);
        ROT_X(BtmP3, aX);
        ROT_X(BtmP4, aX);

        ROT_X(TopP1, aX);
        ROT_X(TopP2, aX);
        ROT_X(TopP3, aX);
        ROT_X(TopP4, aX);


        ROT_Y(BtmP1, aY);
        ROT_Y(BtmP2, aY);
        ROT_Y(BtmP3, aY);
        ROT_Y(BtmP4, aY);

        ROT_Y(TopP1, aY);
        ROT_Y(TopP2, aY);
        ROT_Y(TopP3, aY);
        ROT_Y(TopP4, aY);


        ROT_Z(BtmP1, aZ);
        ROT_Z(BtmP2, aZ);
        ROT_Z(BtmP3, aZ);
        ROT_Z(BtmP4, aZ);

        ROT_Z(TopP1, aZ);
        ROT_Z(TopP2, aZ);
        ROT_Z(TopP3, aZ);
        ROT_Z(TopP4, aZ);


        #local BtmP1 = BtmP1 + Place_Trn;
        #local BtmP2 = BtmP2 + Place_Trn;
        #local BtmP3 = BtmP3 + Place_Trn;
        #local BtmP4 = BtmP4 + Place_Trn;

        #local TopP1 = TopP1 + Place_Trn;
        #local TopP2 = TopP2 + Place_Trn;
        #local TopP3 = TopP3 + Place_Trn;
        #local TopP4 = TopP4 + Place_Trn;



        // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        // DRAW BOX, implementation

              // btm
              triangle{ BtmP1, BtmP2, BtmP3 }
              triangle{ BtmP1, BtmP4, BtmP3 }
              // top
              triangle{ TopP1, TopP2, TopP3 }
              triangle{ TopP1, TopP4, TopP3 }

              // front
              triangle{ BtmP1, BtmP2, TopP2 }
              triangle{ TopP1, TopP2, BtmP1 }
              // back
              triangle{ BtmP3, BtmP4, TopP4 }
              triangle{ TopP3, TopP4, BtmP3 }

              // left
              triangle{ BtmP2, BtmP3, TopP3 }
              triangle{ TopP2, TopP3, BtmP2 }
              // right
              triangle{ BtmP1, BtmP4, TopP4 }
              triangle{ TopP1, TopP4, BtmP1 }

____________________________________________________________________________________________


Sorry for the "meshy" post but I am in a hurry... I will have more time tomorrow
But yes it is a good idea and it has saved me lots of trouble. :)

Best wishes! /A


Post a reply to this message

From: Bald Eagle
Subject: Re: Mesh replacements for primitives?
Date: 8 Aug 2016 19:40:01
Message: <web.57a91764db2c47315e7df57c0@news.povray.org>
"architype" <arc### [at] gmxcom> wrote:

I just saw this - very extensive and informative - Thanks!  :)

Well, I often just play around with "plotting" things, and sometimes parametrics
or isosurfaces or functions are a real pain, so I just calculate things and
"plot" a point with a small sphere.

I suppose if instead of doing that, if each sphere, or box, or whatever was
written to a file as a mesh, then maybe I could "massage" the data with NetFabb
or something, remove the redundant parts, close up holes, and fix the mesh -
then it would all be "one thing".

Lots of stuff to play with, and I certainly do have a few WIPS waiting in the
wings that are large buildings with many identical pieces of furniture and other
items, so this sort of thing will come in handy.


Post a reply to this message

From: architype
Subject: Re: Mesh replacements for primitives?
Date: 9 Aug 2016 00:45:00
Message: <web.57a95f3fdb2c47319403bba30@news.povray.org>
Glad you liked the code. :)
I keep them in my insert menu and often use them in my projects.
I did a demo of the rotated box, the vault below. It works, but
parse time is prohibitive, almost 15 seconds. (My old computer is
not that bad...) I didnt realize my code was that crappy... :/
The mesh is only 12x4x9x12 = 5184 triangles, it shouldnt take 15
seconds to create... But I suppose one could create just a single
arch in this case. But it is most annoying....

I rarely use the complex surfaces, so I cant help you there.

Yep, it is very useful for making architecture and generally objects
that you use more than once.

Best wishes! /A

//-----------------------------------------
// Var

#local VaultR = 5;

#local CofferNum = 12;

#local CofferW = 1.33;
#local CofferH = .5;

#local EdgeDE = CofferW/4;




// LOAD ONCE
#include "MeshPntTrn.Inc"

#local CofferVaultObj=
mesh{

#local CountJ = 3;
#local J = 0;
#while ( J <= CountJ )

 #local CountI = CofferNum-1;
 #local I = 0;
 #while ( I <= CountI )


// Back
#local bW = CofferW;
#local bH = CofferH;
#local bT = CofferW;

#local Init_Trn = <0, VaultR, 0>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


// Edges part 1

#local bW = EdgeDE;
#local bH = CofferH;
#local bT = CofferW;

#local Init_Trn = <CofferW/2-EdgeDE/2, VaultR-EdgeDE/2, 0>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


#local bW = EdgeDE;
#local bH = CofferH;
#local bT = CofferW;

#local Init_Trn = <-CofferW/2+EdgeDE/2, VaultR-EdgeDE/2, 0>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


#local bW = CofferW;
#local bH = CofferH;
#local bT = EdgeDE;

#local Init_Trn = <0, VaultR-EdgeDE/2, -CofferW/2+EdgeDE/2>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"

#local bW = CofferW;
#local bH = CofferH;
#local bT = EdgeDE;

#local Init_Trn = <0, VaultR-EdgeDE/2, CofferW/2-EdgeDE/2>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"



// Edges part 2
#local bW = EdgeDE/2;
#local bH = CofferH;
#local bT = CofferW;

#local Init_Trn = <CofferW/2-EdgeDE/4, VaultR-EdgeDE, 0>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


#local bW = EdgeDE/2;
#local bH = CofferH;
#local bT = CofferW;

#local Init_Trn = <-CofferW/2+EdgeDE/4, VaultR-EdgeDE, 0>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


#local bW = CofferW;
#local bH = CofferH;
#local bT = EdgeDE/2;

#local Init_Trn = <0, VaultR-EdgeDE, -CofferW/2+EdgeDE/4>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"

#local bW = CofferW;
#local bH = CofferH;
#local bT = EdgeDE/2;

#local Init_Trn = <0, VaultR-EdgeDE, CofferW/2-EdgeDE/4>;

#local aX = 180/CofferNum*I;
#local aY = 0;
#local aZ = 0;

#local Place_Trn = <J*CofferW, 0, 0>;

#include "ROT_TRN.tch"


 #local I = I + 1;
 #end

#local J = J + 1;
#end




translate<CofferW/2,0,0>
rotate x*-180/CofferNum/2

translate<CofferW*-2,0,0>
rotate x*90
rotate y*90

translate<0, 1, 0>

}


Post a reply to this message

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