Lscript : Make SubD Hold Corners...

Kryslin

Active member
I have problems with SubD's. I absolutely loathe the task of making hold geometry all over the place. So, I wrote an Lscript to do it for me.

Code:
@script modeler
@warnings
@name SubD Corners

//Author : Steven Pettit
//Date : 21 July 2013
//Version : 1.0

main
{
	selmode(USER);
	ofs = 0.001;
	p_inf = polycount();
	p_cnt = p_inf[1];
	if (p_cnt < 1) error("Select some Polygons!");
	
	reqbegin("Make Hold Geometry");
		reqsize(300,105);
		c1 = ctldistance("Hold Distance",ofs);
		ctlposition(c1,11,15,279,19);
		return if !reqpost();
		ofs = getvalue(c1);
    reqend();
	
	editbegin();
		orig = polygons;
	editend();
	
	wrk = orig;
	
	tmp = nil;
	unweld();
	for(q=1;q<=wrk.count();q++)
	{
		tmp = wrk[q];
		selpolygon(CLEAR);
		selpolygon(SET,POLYID,tmp);
		editbegin();
			p1 = polygons;
			v1 = points;
			v2 = nil;
			v3 = nil;
			vcnt = v1.count();
			for(i=1;i<=vcnt;i++)
			{
				j = i + 1;
				if (j > vcnt) j = 1;
				ov = (pointinfo(v1[j]) - pointinfo(v1[i]));
				v2 += ofs * normalize(ov);
			}
			for(i=1;i<=vcnt; i++)
			{
				j = i - 1;
				if (j < 1) j = vcnt;
				op = pointinfo(v1[i]);
				v3 += op;
				v3 += op + v2[i];
				v3 += op + v2[i] - v2[j];
				v3 += op - v2[j];
			}
			lim = vcnt * 4;
			for(i=0;i<vcnt;i++)
			{
				//make the easy polygons
				tv = nil;
				for(j=0;j<4;j++)
				{
					bo = ((i * 4) + j) + 1;
					tv += addpoint(v3[bo]);
				}
				tp += addpolygon(tv,"Default");
			}
			//Slightly Harder Polygons...
			for(i=0;i<vcnt;i++)
			{
				tv = nil;
				bo = i * 4;
				b0 = bo + 2;
				b1 = bo + 8; if (b1 > lim) b1 -= lim;
				b2 = bo + 7; if (b2 > lim) b2 -= lim;
				b3 = bo + 3; if (b3 > lim) b3 -= lim;
				tv += addpoint(v3[b0]);
				tv += addpoint(v3[b1]);
				tv += addpoint(v3[b2]);
				tv += addpoint(v3[b3]);
				tp += addpolygon(tv,"Default");
			}
			//Last Internal Polygon
			tv = nil;
			for(i=0;i<vcnt;i++)
			{
				tv += addpoint(v3[(i*4)+3]);
			}
			tp += addpolygon(tv,"Default");
		editend();
	}
	selpolygon(CLEAR);
	selpolygon(SET,POLYID,orig);
	removepols();
	selpolygon(CLEAR);
	selpolygon(SET,POLYID,tp);
	mergepoints();
	selpolygon(CLEAR);
}

Surprisingly, It works well. And if I have a problem with adding hold geometry, perhaps someone else will find it useful, too.

Unsurprisingly, my code is a mess. Any help cleaning it up would be appreciated.

What it does is add hold geometry at the corners of each polygon, based on a distance given by the user, which defaults to 1mm.
I've tested it on n-gons, single quads, multiple quads, and triangles. What it doesn't do is split n-gons into quads, or not put hold geometry on shared edges.

I'm going to be working on a Hold Geometry friendly inset in the near future as well.
 

Kryslin

Active member
The script makes extra geometry so that when you apply subdivision to it, the corners aren't completely rounded off; depending on the distance, they can be nearly razor sharp, to a nice filleted edge.

To see what it does : Make a cube, and run the script - change the distance to something greater than 1mm. Apply subdivision. It should still look relatively cube like, instead of a sphere.
 
Last edited:

Kryslin

Active member
Some of the stuff I've been re-working couldn't be bandsawed or cut; Edit Edges is still a little imprecise. So I've been using LWCAD's line tool and Ruler snaps... It works, but it's kind of like cutting a board in half with a hammer.... including occasional misses, hitting your fingers.

So, I decided to see if this could be done, and then figure out how to do it. Knife probably would have been a better tool to use, but I couldn't find any info on whether it's available from lscripts. So I just generated new geometry from the old. I'm happy with the results, even though the code is kind of messy...
 

Dodgy

Worms no more! Free fun!
I tend to use FI's Wrinkle for this sort of task, not available in 64 bit unfortunately, maybe something to add natively to modeller? It's so useful as it always outputs quads, and is one of my main tools for sub division modelling.
 

Attachments

  • Capture.JPG
    Capture.JPG
    79.8 KB · Views: 201

Kryslin

Active member
Updated just a little bit... It no longer replaces the polygon's surface with "Default", but uses the original surface instead.

Code:
@script modeler
@warnings
@name SubD Corners

//Author : Steven Pettit
//Date : 27 July 2013
//Version : 1.01

main
{
	
	selmode(USER);
	ofs = 0.001;
	p_inf = polycount();
	p_cnt = p_inf[1];
	if (p_cnt < 1) error("Select some Polygons!");
	
	reqbegin("Make Hold Geometry");
		reqsize(300,105);
		c1 = ctldistance("Hold Distance",ofs);
		ctlposition(c1,11,15,279,19);
		return if !reqpost();
		ofs = getvalue(c1);
    reqend();
	
	editbegin();
		orig = polygons;
	editend();
	
	wrk = orig;
	
	//debug();
	
	tmp = nil;
	unweld();
	for(q=1;q<=wrk.count();q++)
	{
		tmp = wrk[q];
		selpolygon(CLEAR);
		selpolygon(SET,POLYID,tmp);
		editbegin();
			p1 = polygons;
			v1 = points;
			v2 = nil;
			v3 = nil;
			srfname = p1[1].surface;
			vcnt = v1.count();
			for(i=1;i<=vcnt;i++)
			{
				j = i + 1;
				if (j > vcnt) j = 1;
				ov = (pointinfo(v1[j]) - pointinfo(v1[i]));
				v2 += ofs * normalize(ov);
			}
			for(i=1;i<=vcnt; i++)
			{
				j = i - 1;
				if (j < 1) j = vcnt;
				op = pointinfo(v1[i]);
				v3 += op;
				v3 += op + v2[i];
				v3 += op + v2[i] - v2[j];
				v3 += op - v2[j];
			}
			lim = vcnt * 4;
			for(i=0;i<vcnt;i++)
			{
				//make the easy polygons
				tv = nil;
				for(j=0;j<4;j++)
				{
					bo = ((i * 4) + j) + 1;
					tv += addpoint(v3[bo]);
				}
				tp += addpolygon(tv,srfname);
			}
			//Slightly Harder Polygons...
			for(i=0;i<vcnt;i++)
			{
				tv = nil;
				bo = i * 4;
				b0 = bo + 2;
				b1 = bo + 8; if (b1 > lim) b1 -= lim;
				b2 = bo + 7; if (b2 > lim) b2 -= lim;
				b3 = bo + 3; if (b3 > lim) b3 -= lim;
				tv += addpoint(v3[b0]);
				tv += addpoint(v3[b1]);
				tv += addpoint(v3[b2]);
				tv += addpoint(v3[b3]);
				tp += addpolygon(tv,srfname);
			}
			//Last Internal Polygon
			tv = nil;
			for(i=0;i<vcnt;i++)
			{
				tv += addpoint(v3[(i*4)+3]);
			}
			tp += addpolygon(tv,srfname);
		editend();
	}
	selpolygon(CLEAR);
	selpolygon(SET,POLYID,orig);
	removepols();
	selpolygon(CLEAR);
	selpolygon(SET,POLYID,tp);
	mergepoints();
	selpolygon(CLEAR);
}
 
Top Bottom