Lscript : Make SubD Hold Corners...

Kryslin

New 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.
 
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:
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...
 
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: 412
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);
}
 
Thanks!
tJGL61i.png



yeah, FI's Wrinkle was neat, but 32bit only...
h3q18Zh.gif
it is missed.

 
Folks, this is literally one of the most important tools in LW I use it all the time BUT....Is there anyway to make this also have a slider to control the distance instead of the manual entry of the data and ctrl+z if it's off a bit?
 
Folks, this is literally one of the most important tools in LW I use it all the time BUT....Is there anyway to make this also have a slider to control the distance instead of the manual entry of the data and ctrl+z if it's off a bit?
Swift Edge Loop has percentage slider, and metric slider, and much more functionality, see website:
http://swiftedgeloop.trueart.eu

IIRC, Lscript does not support interactive tools.
 


should be possible, (guesstimating)
CP realtime smooth for example has realtime sliders.
simple script too.

@warnings
@version 2.7
@name cp_RealTimeSmooth
/*
Copyright © Chris Peterson
by chris peterson
[email protected]
http://www.chrisepeterson.com
july 15, 2009

This script will allow you to preview your smooth and only use a single undo.
*/

c;
firstChange = false;
main
{
pntCnt = pointcount();
if(!pntCnt)
{
error("These are not the points you are looking for, move along");
break;
}

smStrength = recall("smStrength",1);
smIterations = recall("smIterations",1);
reqbegin("cp_RealTimeSmooth");
c[1] = ctlslider("Strength",smStrength,1,100);
c[2] = ctlslider("Iterations",smIterations,1,100);
ctlrefresh(c[1], "updateValue");
ctlrefresh(c[2], "updateValue");
if(!reqpost())
{
undo();
return;
}
smStrength = getvalue(c[1]);
smIterations = getvalue(c[2]);
store("smStrength",smStrength);
store("smIterations",smIterations);
reqend();
}
updateValue: value
{
doSmooth();
}
doSmooth
{
smStrength = getvalue(c[1]);
smIterations = getvalue(c[2]);
selmode(USER);
if(firstChange == false)
{
smooth(smIterations,smStrength);
firstChange = true;
}
else
{
undo();
smooth(smIterations,smStrength);
}
}

plugins can be found here >
please donate.

 
Interactive modeling tools have GUI inside of the Numeric window. This is the LWXPanel.
Lscript can only open the LWPanel, the user presses control in it, script closes GUI, updates the mesh, and reopens the LWPanel.
 
Sensei : You can take into account certain events happening in the panel that lscript opens up through the various callbacks. So, if the value for the inset changes, you could update the the model.

I have found that it is a pain in the rear to do, however.

You'd undo the previous update, do the operation with the new inset value. You could probably make this more efficient, say by copying the initial geometry to the clipboard instead of using the undo system. And getting modeler to refresh the screen appears to be a black art in both lscript and python,
 
Sensei : You can take into account certain events happening in the panel that lscript opens up through the various callbacks. So, if the value for the inset changes, you could update the the model.

I have found that it is a pain in the rear to do, however.

You'd undo the previous update, do the operation with the new inset value. You could probably make this more efficient, say by copying the initial geometry to the clipboard instead of using the undo system. And getting modeler to refresh the screen appears to be a black art in both lscript and python,
This is cheat in Lscript. In C/C++ plugin there is special class of plugins for making interactive tools (LWMeshEditTool). It uses Numeric window and LWXPanels.
 
Sensei : You can take into account certain events happening in the panel that lscript opens up through the various callbacks. So, if the value for the inset changes, you could update the the model.

I have found that it is a pain in the rear to do, however.

You'd undo the previous update, do the operation with the new inset value. You could probably make this more efficient, say by copying the initial geometry to the clipboard instead of using the undo system. And getting modeler to refresh the screen appears to be a black art in both lscript and python,
did you check the script i posted ?
the CP one ?

 
Back
Top