Thread cutting script - WIP  1-20  21-40  41-60  …  81-95

Next
 From:  Martin (MARTIN3D)
5451.1 
I'm working on a simple thread cutting script that should output a Metric M10 x 1.5 thread. Everything works with a straight helix but to make it realistic the thread has to taper off at the end. I therefore add a 1-turn tapered helix, join it with the straight helix and sweep the cutting profile around. Unfortunately I'm getting an artifact where both helix meet and I can't figure out why.



I attached the script part that makes the cutting object.


UPDATE:
From now on you will find the most recent version of the "makeExternalThread" script attached to this post.
Adding new thread sizes is simple, just add one line per size to the "makeExternalThread.htm" file (note the ".htm" extension).
Open the file in a plain text editor and find instructions inside on how to do it.

EDITED: 17 Oct 2012 by MARTIN3D


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.2 In reply to 5451.1 
Hi Martin, it looks like the sweep is having a problem with the miter joint.

When you do a 1-rail sweep along a path that has a sharp corner in it, the sweep will place a miter joint between the 2 different segments of the path where they meet at a sharp kink type area.

That's done by a process of extending the surfaces and then intersecting them with one another. When the rail is a swoopy 3D curve instead of a 2D curve it can be pretty difficult for the pieces to completely intersect with one another and you can get just the extensions coming through which I believe is the artifact that you're seeing there.

For a 3D swoopy path curve you may want to make sure that the rail is totally smooth and does not have any sharp kink areas in it, for a smooth path it won't try to do mitering or if you do want to do a path with a sharp kink in it you may need to do the sweep in different sections for each separate segment instead of having a joined rail with a kink in it, and possibly have profiles positioned at the start and end of the segments so that you can control how the pieces meet up.

But yeah what you show there can be the result of trying to get a mitered corner at sharp junctures on a swoopy 3D path curve.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.3 In reply to 5451.1 
You could also possibly do a rebuild on the rail curve that has a kink in it, if you use # of points mode for the rebuild and don't preserve corners, it will make one long smooth curve as the rebuild result and eliminate the kink that the sweeper is trying to miter currently.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.4 In reply to 5451.1 
Yeah I see now you've got a helix section and then a tapered helix section - those will have a different tangent at the spots where they touch each other so that means there is a sharp kink between them. Probably the sweeps generated along those different sections do not totally cleanly intersect with one another which would be needed for the mitering to be processed.

In the future I want to add a different miter mode for 3D swoopy type paths where it will do something more like put in an angled profile piece at the juncture areas instead of doing a true miter with the extension and intersection methods, that might be what you would want here.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.5 In reply to 5451.4 
Thanks Michael, doing a manual rebuild command on the rail with 100 points and Keep corners unchecked produces a clean sweep.
I added a rebuild to my script but when I do the rebuild via the attached script the sweep still has an artifact.
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.6 In reply to 5451.5 
Hi Martin, in your new script, replace this:

/*mode*/ factory.setInput( 1, '#Points' );

With this:

/*mode*/ factory.setInput( 1, 'numpoints' );

and then you should be ok - the mode can be either: 'refit' or 'numpoints' - otherwise it will still be in "refit to tolerance" mode, which will only ignore kinks if they are not too large of an angle. It can be misleading to just look at UI text, often the actual scripting value is not exactly the same as the text you see in the UI, if you look in rebuild.htm you can find the actual value that gets used on the factory here (see the part of the drop-down control I've marked with ****):

code:
	<moi:Select id="mode" oninit="UpdateControls();" onchange="UpdateControls();">
		<moi:Option ****value="refit"**** textid="Rebuild refit to tolerance mode"/>
		<moi:Option ****value="numpoints"**** textid="Rebuild num points mode"/>
	</moi:Select>


The text that's displayed in the UI comes from the strings.txt file and will be different if a different language setting is being used, it's often slightly different than the script values.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.7 In reply to 5451.6 
Thank you Michael for showing me how to find input names of undocumented commands. I'm still having difficulties with the sweep but need to address this with fresh eyes.

In the meantime here's a working script that produces a 30 mm long piece of metric M10 x 1.5 rod. The thread profile is simplified without radius.
By editing the variables at the beginning of the script file different threads can be made.
The longer the thread length though the longer it takes for the sweep and boolean operations to finish. Making a 300 mm long rod took between 5 and 10 minutes (I didn't stop the exact time).

Maybe a good script to measure performance. There's the moi.ui.showViewportDisplayTime=true; function to measure vieport update time but is there some sort of time function in the MoI JavaScript language?

EDITED: 4 Oct 2012 by MARTIN3D

Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
5451.8 In reply to 5451.7 
There is a script "Toggle redraw time display."
http://moi3d.com/forum/index.php?webtag=MOI&msg=5285.1
Do not know if this is relevant.
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.9 In reply to 5451.7 
Hi Martin,

> but is there some sort of time function in the MoI JavaScript language?

Check out some of the answers here:
http://stackoverflow.com/questions/1210701/compute-elapsed-time-in-javascript

Basically you can do something like:


var start = new Date();


...... do stuff ......


var end = new Date();

var diff = end - start;


I think the difference will be a value in milliseconds.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.10 In reply to 5451.9 
Thanks Michael!

Here's the final version of my thread making script.

I'm not so confident with the UI though. It starts to behave strange when I run the script more than once i.e. the UI dissapears after some time.
Also the transition from the thread part to the unthreaded part is a cheat. I simply join the parts using a dowel. The correct way would be one cylinder and a thread that tapers to zero using a tapered helix but that turned out to be too fragile to work reliable.

It would be nice if there where an updated tapered helix function that allows to set the start of the taper to any point between start and end of the helix e.g. for a 50 mm long helix a setting of zero would give the tapered helix we already know while a setting of 25 would produce a helix that runs with the start radius straight up to the middle and then starts to taper. This would be better than having to join two helix curves get different tangents and problems with the Sweep function.

EDIT: I deleted the attachement and attached the newest version of this script to the first post of this thread.

EDITED: 12 Oct 2012 by MARTIN3D

Image Attachments:
Size: 25.4 KB, Downloaded: 108 times, Dimensions: 223x314px
Size: 28.9 KB, Downloaded: 131 times, Dimensions: 120x346px
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.11 In reply to 5451.10 
> It starts to behave strange when I run the script more than once i.e. the UI dissapears after some time.

I saw this happen once but I've been unable to repeat it reliably so I'm having a hard time debugging it.

It may be the UI getting stuck in some particular mode due to calling the native HTML alert() method, try calling moi.ui.alert( 'text' ); rather than moi.ui.commandUI.alert - the second one there calls the alert method on the HTML Window object, and that puts up a different kind of dialog that MoI is not in as much direct control over.


> would give the tapered helix we already know while a setting of 25 would produce a helix that
> runs with the start radius straight up to the middle and then starts to taper.

The problem is that making a taper start suddenly at one single point like that will result in the same problem that you had before - that would make 2 different portions that had a different tangent where they touched, those different helix shapes naturally have different tangents at that juncture area.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.12 In reply to 5451.11 
Thanks Michael, yes with the other alert it seems to work reliable.
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.13 In reply to 5451.12 
Hi Martin, so actually it's not that alert at all, I looked into it some more and it looks like your script is running into a "timeout" mechanism in the script interpreter, due to the continuously spinning while loop here:

code:
	while (!moi.ui.commandUI.GetStart()) {		
	}


A loop like that is going to continuously burn CPU time and at some point the script interpreter notices that it's just churning CPU in a loop and bails on the script.

I should be able to disable that timeout mechanism, but in the meantime you should instead use an event loop for that kind of a thing, if you wait for a UI event that will pause the script until an event is actually generated, the method that you're doing now does not do an actual wait, it's called "polling" where it's just actively checking over and over and over again.

To do the event based method, replace that while loop with this:

code:
	var dlg = moi.ui.commandDialog;

	while ( 1 ) {
	
		dlg.waitForEvent();
		
		if ( dlg.event == 'startbutton' )
			break;
	}


You can also remove the GetStart() script at the top of makethread.htm and also remove the onbuttonclick="" handler on the start button, it's enough for the start button to just have an id value, any control inside of the command UI area will generate a UI event with that id when pressed.


Note that there is still a loop, but that's only because it's possible for other events to be generated too like when other controls are clicked, you want to loop until you get the right event but by calling waitForEvent() on a "waitable object" (if you don't have a pointpicker or object picker then the "command dialog" object can work, it's a waitable object that represents the command UI panel) you won't be burning CPU, the script will actually suspend at that point until a UI event is generated, then it wakes up.


Also if you give your start button an id="done" , you can then #include "WaitForDialogDone.js" in your script and then use WaitForDialogDone(); which is a packaged up function that does that exact same kind of loop in it, it just looks for a UI event named "done" instead of "startbutton".


I've never seen this script interruption mechanism kick in before, so that was kind of mysterious but it was good to find out about it since there may be other situations where you're doing a whole lot of number crunching processing where you would need the script to crunch away in a tight loop for some time, so it's definitely something that I need to disable in the script engine.


- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.14 In reply to 5451.12 
Hi Martin, so it definitely is this script timeout thing - if you just run makethread once and just let it sit there for about 20 seconds, it will get interrupted and then it will immediately interrupt when you launch it after that as well.

I will be eliminating that for the next beta but for now if you switch to the event-waiting method that I wrote above it will solve the problem, because it's only time actually spent directly in the script engine itself that counts for the timeout period, when the script calls into MoI the time that MoI's backend stuff is working on processing things (or waiting for an event) does not count towards the timeout period.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.15 In reply to 5451.12 
And the alert doesn't have anything to do with it - there was actually a problem with that particular other alert method back earlier in v3 but it's actually been fixed for quite a while now.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.16 In reply to 5451.15 
Hi Michael,

I'm glad you figured that out. I already added the method you suggested but I also want to make the thread more accurate. For this I need a fillet radius on one side of the thread cutting object as shown on the right side:


My problem is selecting this point via script and than to use the Fillet factory correctly. I can't even get filleting all corners to work.

code:
var threadDiameter=10;
var threadPitch=1.5	

/*draw thread cutting profile*/
frame = moi.vectorMath.createFrontFrame();
frame.origin = moi.vectorMath.createPoint( threadDiameter/2, 0, -1*threadPitch );
factory = moi.command.createFactory( 'polygonedge' );
factory.setInput( 0, frame );
factory.setInput( 1, moi.vectorMath.createPoint( threadDiameter/2, 0, 0 ) );
factory.setInput( 2, 3 );
factory.commit();
moi.geometryDatabase.selectAll();

/*round off all corners*/
factory = moi.command.createFactory( 'fillet' );
factory.setInput( 0, moi.geometryDatabase.getSelectedObjects() );
factory.setInput( 3, 0.14434 * threadPitch );
factory.setInput( 4, "circular" );
factory.commit();
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.17 In reply to 5451.16 
Hi Martin, to do a curve fillet you need to create a list with a boolean entry for each vertex and add that to the factory on input 2.

Normally this is done in the Fillet command by calling factory.generateVertices(), then letting the user pick the vertices which are temporary point objects and then calling factory.finishedPickingVertices() at the end of the picking stage, but you can instead directly create a list and add the boolean flags to it, there should be one flag for each segment of the input curve.

So something like this should work:

code:
    factory = moi.command.createFactory( 'fillet' );

    var vertflags = moi.createList();
    vertflags.add( true );
    vertflags.add( false );
    vertflags.add( false );
    factory.setInput( 2, vertflags );

    factory.setInput( 0, moi.geometryDatabase.getSelectedObjects() );
    factory.setInput( 3, 1.0 );
    factory.setInput( 4, "circular" );
    factory.commit();


- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Martin (MARTIN3D)
5451.18 In reply to 5451.17 
Cool, thanks a lot for the help. I would have never got this to work.
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
5451.19 In reply to 5451.13 
Michael, re: script timeout.

When I was calculating "fibonacci" points with a fibonacci script with nested For Loops, after about
12,000 points, MoI would quit working. I was wondering if this may have been due to this "script timeout" ?

Or maybe it was some kind of memory used up thing?

Thank you,
Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
5451.20 In reply to 5451.19 
Hi Brian, yeah most likely that was hitting the timeout as well, it will be disabled in the next v3 beta.

12,000 points is not really that much memory so it's more likely that it was the same timeout problem.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All

 

 
Show messages:  1-20  21-40  41-60  61-80  81-95