[Sidefx-houdini-list] Space filling circles

Andrew D Lyons tstexture at gmail.com
Wed Aug 5 19:07:23 EDT 2009


That's an interesting problem. Not exactly circular - but close:

Drop this in a textport:
#######################################################

# Automatically generated script: Wednesday August 05, 16:06
\set noalias = 1
set saved_path = `execute("oppwf")`
opcf /obj

# Node circle_cells (Object/geo)
opadd -n geo circle_cells
oplocate -x 12.6117 -y 2.05949 circle_cells
opspareds '    group { 	name	"stdswitcher5" 	label	"Transform"  	parm
{ 	    name	"keeppos" 	    baseparm 	    joinnext 	    export	none 	}
	parm { 	    name	"pre_xform" 	    baseparm 	    export	none 	} 	parm
{ 	    name	"xOrd" 	    baseparm 	    joinnext 	    export	none 	}
	parm { 	    name	"rOrd" 	    baseparm 	    export	none 	} 	parm { 	
 name	"t" 	    baseparm 	    export	all 	} 	parm { 	    name	"r" 	
baseparm 	    export	all 	} 	parm { 	    name	"s" 	    baseparm 	
export	none 	} 	parm { 	    name	"p" 	    baseparm 	    export	none 	}
	parm { 	    name	"scale" 	    baseparm 	    export	none 	} 	parm { 	
  name	"lookatpath" 	    baseparm 	    export	none 	} 	parm { 	
name	"lookup" 	    baseparm 	    export	none 	} 	parm { 	
name	"pathobjpath" 	    baseparm 	    export	none 	} 	parm { 	
name	"roll" 	    baseparm 	    export	none 	} 	parm { 	    name	"pos"
	    baseparm 	    export	none 	} 	parm { 	    name	"uparmtype" 	
baseparm 	    export	none 	} 	parm { 	    name	"pathorient" 	
baseparm 	    export	none 	} 	parm { 	    name	"up" 	    baseparm 	
export	none 	} 	parm { 	    name	"bank" 	    baseparm 	    export	none
	}     }      group { 	name	"stdswitcher5_1" 	label	"Material"  	parm
{ 	    name	"shop_materialpath" 	    baseparm 	    joinnext 	
export	none 	} 	parm { 	    name	"shop_materialopts" 	    baseparm 	
 export	none 	}     }      group { 	name	"stdswitcher5_2"
	label	"Render"  	parm { 	    name	"tdisplay" 	    baseparm 	
export	none 	} 	parm { 	    name	"display" 	    baseparm 	
export	none 	} 	parm { 	    name	"vm_phantom" 	    label	"Phantom" 	
 type	toggle 	    default	{ "0" } 	    range	{ 0 1 } 	    export	none
	    parmtag	{ "spare_category" "Render" } 	} 	parm { 	
name	"vm_renderable" 	    label	"Renderable" 	    type	toggle 	
default	{ "1" } 	    range	{ 0 1 } 	    export	none 	    parmtag	{
"spare_category" "Render" } 	} 	group { 	    name	"folder0" 	
label	"Shading"  	    parm { 		name	"categories" 		label	"Categories"
		type	string 		default	{ "" } 		help	"A list of tags which can be
used to select the object" 		range	{ 0 1 } 		export	none 		parmtag	{
"spare_category" "Shading" } 	    } 	    parm { 		name	"reflectmask"
		label	"Reflection Mask" 		type	oplist 		default	{ "*" } 		range	{ 0
1 } 		export	none 		parmtag	{ "oprelative" "/obj" } 		parmtag	{
"opfilter" "!!OBJ/GEOMETRY!!" } 		parmtag	{ "spare_category" "Shading"
} 		parmtag	{ "opexpand" "1" } 	    } 	    parm { 		name	"lightmask"
		label	"Light Mask" 		type	oplist 		default	{ "*" } 		range	{ 0 1 }
		export	none 		parmtag	{ "oprelative" "/obj" } 		parmtag	{ "opfilter"
"!!OBJ/LIGHT!!" } 		parmtag	{ "spare_category" "Shading" } 		parmtag	{
"opexpand" "1" } 	    } 	    parm { 		name	"vm_volumefilter"
		label	"Volume Filter" 		type	string 		default	{ "gaussian" }
		menu	{ 		    "box"	"Box Filter" 		    "gaussian"	"Gaussian" 		
"bartlett"	"Bartlett (triangle)" 		    "catrom"	"Catmull-Rom" 		
"hanning"	"Hanning" 		    "blackman"	"Blackman" 		    "sinc"	"Sinc
(sharpening)" 		} 		range	{ 0 1 } 		export	none 		parmtag	{
"spare_category" "Shading" } 	    } 	    parm {
		name	"vm_volumefilterwidth" 		label	"Volume Filter Width"
		type	float 		default	{ "1.5" } 		range	{ 0.001 5 } 		export	none
		parmtag	{ "spare_category" "Shading" } 	    } 	    parm {
		name	"vm_matte" 		label	"Matte shading" 		type	toggle 		default	{
"0" } 		range	{ 0 1 } 		export	none 		parmtag	{ "spare_category"
"Shading" } 	    } 	}  	group { 	    name	"folder0_1" 	
label	"Sampling"  	    parm { 		name	"geo_velocityblur"
		label	"Geometry Velocity Blur" 		type	toggle 		default	{ "0" }
		range	{ 0 1 } 		export	none 		parmtag	{ "spare_category" "Sampling"
} 	    } 	}  	group { 	    name	"folder0_2" 	    label	"Dicing"  	
parm { 		name	"vm_shadingquality" 		label	"Shading Quality"
		type	float 		default	{ "1" } 		range	{ 0 10 } 		export	none
		parmtag	{ "spare_category" "Dicing" } 	    } 	    parm {
		name	"vm_rayshadingquality" 		label	"Ray Shading Quality"
		type	float 		default	{ "1" } 		range	{ 0 10 } 		export	none
		parmtag	{ "spare_category" "Dicing" } 	    } 	}  	group { 	
name	"folder0_3" 	    label	"Geometry"  	    parm {
		name	"vm_rmbackface" 		label	"Backface Removal (Mantra)"
		type	toggle 		default	{ "0" } 		range	{ 0 1 } 		export	none
		parmtag	{ "spare_category" "Geometry" } 	    } 	    parm {
		name	"shop_geometrypath" 		label	"Procedural Shader" 		type	oppath
		default	{ "" } 		range	{ 0 1 } 		export	none 		parmtag	{
"oprelative" "." } 		parmtag	{ "opfilter" "!!SHOP/GEOMETRY!!" }
		parmtag	{ "spare_category" "Geometry" } 	    } 	    parm {
		name	"vm_rendersubd" 		label	"Polygons As Subdivision (Mantra)"
		type	toggle 		default	{ "0" } 		range	{ 0 1 } 		export	none
		parmtag	{ "spare_category" "Geometry" } 	    } 	    parm {
		name	"vm_renderpoints" 		label	"Render As Points (Mantra)"
		type	toggle 		default	{ "0" } 		range	{ 0 1 } 		export	none
		parmtag	{ "spare_category" "Geometry" } 	    } 	    parm {
		name	"vm_metavolume" 		label	"Metaballs as Volume" 		type	toggle
		default	{ "0" } 		range	{ 0 1 } 		export	none 		parmtag	{
"spare_category" "Geometry" } 	    } 	    parm { 		name	"vm_coving"
		label	"Coving" 		type	integer 		default	{ "1" } 		menu	{ 		
"0"	"Disable Coving" 		    "1"	"Coving for displacement/sub-d" 		
"2"	"Coving for all primitives" 		} 		range	{ 0 10 } 		export	none
		parmtag	{ "spare_category" "Geometry" } 	    } 	    parm {
		name	"vm_computeN" 		label	"Automatically Compute Normals"
		type	toggle 		default	{ "1" } 		range	{ 0 1 } 		export	none
		parmtag	{ "spare_category" "Geometry" } 	    } 	}      }      group
{ 	name	"stdswitcher5_3" 	label	"Misc"  	parm { 	    name	"use_dcolor"
	    baseparm 	    export	none 	} 	parm { 	    name	"dcolor" 	
baseparm 	    export	none 	} 	parm { 	    name	"picking" 	    baseparm
	    export	none 	} 	parm { 	    name	"pickscript" 	    baseparm 	
export	none 	} 	parm { 	    name	"caching" 	    baseparm 	
export	none 	} 	parm { 	    name	"vport_shadeopen" 	    baseparm 	
export	none 	} 	parm { 	    name	"vport_displayassubdiv" 	    baseparm
	    invisible 	    export	none 	}     }  ' circle_cells
opset -S on circle_cells
opparm circle_cells use_dcolor ( off )
chautoscope circle_cells +tx +ty +tz +rx +ry +rz +sx +sy +sz
opset -d on -r off -h off -f off -y off -t off -l off -s off -u off -c
off -e on -b off -x off circle_cells
opexprlanguage -s hscript circle_cells
opcf circle_cells

# Node circle1 (Sop/circle)
opadd -n circle circle1
oplocate -x 3.41176 -y 0.0882355 circle1
opparm circle1 type ( poly ) orient ( zx ) rad ( 21 21 ) divs ( 100 )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off circle1
opexprlanguage -s hscript circle1

# Node triangulate2d1 (Sop/triangulate2d)
opadd -n triangulate2d triangulate2d1
oplocate -x 3.41176 -y -1.15882 triangulate2d1
opparm triangulate2d1 refine ( on ) maxarea ( 2 ) minangle ( 30 )
maxnewpts ( 19565 ) removeduplicatepoints ( off )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off triangulate2d1
opexprlanguage -s hscript triangulate2d1

# Node facet1 (Sop/facet)
opadd -n facet facet1
oplocate -x 3.50951 -y -3.19412 facet1
opparm facet1 unique ( on )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off facet1
opexprlanguage -s hscript facet1

# Node foreach1 (Sop/foreach)
opadd -n foreach foreach1
oplocate -x 3.41176 -y -5.02471 foreach1
chblockbegin
chadd -t 0 0 foreach1 numrange2
chkey -t 0 -v 10 -m 0 -a 0 -A 0 -T a  -F 'nprims("../" + opinput(".",
0))-1' foreach1/numrange2
chblockend
opparm foreach1 fortype ( number ) numrange ( 0 numrange2 1 )
opset -d on -r on -h off -f off -y off -t off -l off -s off -u off -c
off -e on -b off foreach1
opexprlanguage -s hscript foreach1
opcf foreach1

# Node each1 (Sop/each)
opadd -n each each1
oplocate -x 0.6102 -y 4.8513 each1
chblockbegin
chadd -t 0 0 each1 attribtol
chkey -t 0 -v 0.001 -m 0 -a 0 -A 0 -T a  -F 'ch("../attribtol")' each1/attribtol
chadd -t 0 0 each1 attribval1
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "1", 0)' each1/attribval1
chadd -t 0 0 each1 attribval2
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "2", 0)' each1/attribval2
chadd -t 0 0 each1 attribval3
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "3", 0)' each1/attribval3
chadd -t 0 0 each1 attrib
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F
'ifs(!!strcmp(chs("../fortype"), "attrib"), "", chs("../attrib"))'
each1/attrib
chadd -t 0 0 each1 group
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F
'ifs(!!strcmp(chs("../fortype"), "group"), "", stamps("..",
chs("../forstamp"), ""))' each1/group
chadd -t 0 0 each1 feedback
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F '!ch("../mergeresults")' each1/feedback
chblockend
opparm each1 feedback ( feedback ) group ( group ) attrib ( attrib )
attribval ( attribval1 attribval2 attribval3 ) attribtol ( attribtol )
forpath ( .. )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off each1
opexprlanguage -s hscript each1

# Node delete2 (Sop/delete)
opadd -n delete delete2
oplocate -x 0.6102 -y 3.89295 delete2
chblockbegin
chadd -t 0 0 delete2 rangeend
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F '$N' delete2/rangeend
chadd -t 0 0 delete2 filter
chkey -t 0 -v 1 -m 0 -a 0 -A 0 -T a  -F 'stamp("../", "FORVALUE", 0)
== prim("../" + opinput(".", 0), $PR, "__primnum", 0)' delete2/filter
chblockend
opparm delete2 negate ( keep ) groupop ( filter ) filter ( filter )
pattern ( "" )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off delete2
opexprlanguage -s hscript delete2

# Node fit1 (Sop/fit)
opadd -n fit fit1
oplocate -x 0.610753 -y 0.946953 fit1
opparm fit1 stdswitcher ( 2 2 2 ) method ( interp ) orderu ( 3 )
orderv ( 3 ) smooth ( 0.343 ) scope ( breakpnt ) dataparmv ( uniform )
closeu ( wu ) closev ( wv ) corners ( on )
opset -d on -r on -h off -f off -y off -t off -l off -s off -u off -c
off -e on -b off fit1
opexprlanguage -s hscript fit1

# Node circle1 (Sop/circle)
opadd -n circle circle1
oplocate -x 3.01075 -y 3.7 circle1
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off circle1
opexprlanguage -s hscript circle1

# Node resample1 (Sop/resample)
opadd -n resample resample1
oplocate -x 0.622517 -y 2.92353 resample1
opparm resample1 edge ( on ) dolength ( off ) dosegs ( on ) segs ( 2 )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off resample1
opexprlanguage -s hscript resample1

# Node delete1 (Sop/delete)
opadd -n delete delete1
oplocate -x 0.610753 -y 1.85283 delete1
chblockbegin
chadd -t 0 0 delete1 rangeend
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F '$N' delete1/rangeend
chblockend
opparm delete1 entity ( point ) groupop ( range ) range ( -1 rangeend )
opset -d off -r off -h off -f off -y off -t on -l off -s off -u off -c
off -e on -b off delete1
opexprlanguage -s hscript delete1
oporder -e each1 delete2 fit1 circle1 resample1 delete1
opcf ..

# Node __PRIMNUM (Sop/attribcreate)
opadd -n attribcreate __PRIMNUM
oplocate -x 3.41176 -y -4.07765 __PRIMNUM
chblockbegin
chadd -t 0 0 __PRIMNUM value1
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F '$PR' __PRIMNUM/value1
chblockend
opparm __PRIMNUM name ( __primnum ) varname ( __PRIMNUM ) class (
primitive ) value ( value1 0 0 0 )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off __PRIMNUM
opexprlanguage -s hscript __PRIMNUM

# Node foreach2 (Sop/foreach)
opadd -n foreach foreach2
oplocate -x 3.50951 -y -2.29415 foreach2
opparm foreach2 fortype ( number ) numrange ( 0 4 1 ) mergeresults ( off )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off foreach2
opexprlanguage -s hscript foreach2
opcf foreach2

# Node each1 (Sop/each)
opadd -n each each1
oplocate -x 0.6102 -y 4.8513 each1
chblockbegin
chadd -t 0 0 each1 attribtol
chkey -t 0 -v 0.001 -m 0 -a 0 -A 0 -T a  -F 'ch("../attribtol")' each1/attribtol
chadd -t 0 0 each1 attribval1
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "1", 0)' each1/attribval1
chadd -t 0 0 each1 attribval2
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "2", 0)' each1/attribval2
chadd -t 0 0 each1 attribval3
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F 'stamp("..",
chs("../forstamp") + "3", 0)' each1/attribval3
chadd -t 0 0 each1 attrib
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F
'ifs(!!strcmp(chs("../fortype"), "attrib"), "", chs("../attrib"))'
each1/attrib
chadd -t 0 0 each1 group
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F
'ifs(!!strcmp(chs("../fortype"), "group"), "", stamps("..",
chs("../forstamp"), ""))' each1/group
chadd -t 0 0 each1 feedback
chkey -t 0 -v 0 -m 0 -a 0 -A 0 -T a  -F '!ch("../mergeresults")' each1/feedback
chblockend
opparm each1 feedback ( feedback ) group ( group ) attrib ( attrib )
attribval ( attribval1 attribval2 attribval3 ) attribtol ( attribtol )
forpath ( .. )
opset -d off -r off -h off -f off -y off -t off -l off -s off -u off
-c off -e on -b off each1
opexprlanguage -s hscript each1

# Node divide2 (Sop/divide)
opadd -n divide divide2
oplocate -x 0.6102 -y 3.42343 divide2
opparm divide2 convex ( off ) dual ( on )
opset -d on -r on -h off -f off -y off -t off -l off -s off -u off -c
off -e on -b off divide2
opexprlanguage -s hscript divide2
oporder -e each1 divide2
opcf ..
oporder -e circle1 triangulate2d1 facet1 foreach1 __PRIMNUM foreach2
opcf ..

opcf /obj
opcf circle_cells
opwire -n circle1 -0 triangulate2d1
opwire -n foreach2 -0 facet1
opwire -n __PRIMNUM -0 foreach1
opcf foreach1
opwire -n -i 0 -0 each1
opwire -n each1 -0 delete2
opwire -n delete1 -0 fit1
opwire -n delete2 -0 resample1
opwire -n resample1 -0 delete1
opcf ..
opwire -n facet1 -0 __PRIMNUM
opwire -n triangulate2d1 -0 foreach2
opcf foreach2
opwire -n -i 0 -0 each1
opwire -n each1 -0 divide2
opcf ..
opcf ..
opcf $saved_path

######################################################

2009/8/5 Doug Struthers <dragonfly at dougstruthers.com>:
> Thanks for your inputs.
>
> Since there do not need to be thousands of them I bet I can iterate on them
> to get a close approximation without taking a long long time to compute.
>
> It is intriguing to think that there may be a function with dops that the
> solution falls out of but I am still a way down the learning curve with all
> the functionality that exists in vops let alone rolling my own.
>
> Cheers
>
> Doug
>
> On Wed, Aug 5, 2009 at 9:09 AM, Gene Dreitser <keyframe at rogers.com> wrote:
>
>>
>> Might also be worth it to take a look at the output of the isooffset sop
>> using the 'tetra-mesh' output type.  Tetra-type set to 'cubes'.
>>
>> While it will not pack perfectly, it DOES create a predictable pattern of
>> rows and columns that one might be able to make use, and as an added bonus,
>> it can use ray-intersect to sample the original mesh.
>>
>> Best,
>>
>> G
>>
>>  --
>> Gene Dreitser
>> Loki Visual Effects
>> p: 416.532.5654 // c: 416.803.0682 // www.lokivfx.com
>>
>>
>>
>> ----- Original Message ----
>> From: Andy Nicholas <andy at andynicholas.com>
>> To: sidefx-houdini-list at sidefx.com
>> Sent: Wednesday, August 5, 2009 12:05:13 PM
>> Subject: Re: [Sidefx-houdini-list] Space filling circles
>>
>> Hi Doug,
>> Are you asking this because you know of this being done somewhere else? I
>> only ask because I just Googled this (out of my own interest), and judging
>> on how many papers are written on this topic, I'd say that it's a
>> non-trivial problem to solve.
>>
>> The only thing that springs to mind, would be to create an iterative
>> approach, using the SOP solver or the Feedback SOP (proto_install).
>>
>> Note that I haven't tested this, or fully thought it through, but the
>> following... might... just...  work...
>>
>> Start off with a triangular polygon with a random sized disc at each
>> vertex so that their circumferences touch. From that, take a pair of discs
>> and create another randomly sized one and place it (using simple
>> trigonometry) so that it touches the first two. Extend the triangle into a
>> four sided polygon with the new point at the center of the new disc.
>> Repeat the process, but ignoring any discs internal to the polygon.
>>
>> I can see this approach breaking down if you ever have a non-convex
>> polygon, but there are probably some constraints that you could figure out
>> that will prevent this from happening.
>>
>> Andy
>>
>>
>>
>>
>> > Hi
>> >
>> > Can anyone point me to a Houdini method (or other solution) for packing
>> > random sized circles so that they are tightly packed and each
>> > circumference
>> > just touches its neighbors?
>> >
>> > Thanks
>> >
>> > Doug
>> >
>> > --
>> > www.dougstruthers.com
>> > _______________________________________________
>> > Sidefx-houdini-list mailing list
>> > Sidefx-houdini-list at sidefx.com
>> > https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>> >
>>
>>
>> _______________________________________________
>> Sidefx-houdini-list mailing list
>> Sidefx-houdini-list at sidefx.com
>> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>>
>> _______________________________________________
>> Sidefx-houdini-list mailing list
>> Sidefx-houdini-list at sidefx.com
>> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>>
>
>
>
> --
> www.dougstruthers.com
> _______________________________________________
> Sidefx-houdini-list mailing list
> Sidefx-houdini-list at sidefx.com
> https://lists.sidefx.com:443/mailman/listinfo/sidefx-houdini-list
>



-- 
=======================================
Andrew D Lyons | Digital Artist | http://www.tstex.com
=======================================



More information about the Sidefx-houdini-list mailing list