Scripting BLEND

Next
 From:  bemfarmer
6955.1 
It is possible to Script BLEND between two logarithmic curves created by script, and combined into an objectlist.
However, the ends of the two curves blended seem to be selected by default, as the two closest together.

Are there any other Blend inputs, other than the 5 shown in Blend.js, which would enable the two desired endpoints to be input?

Or could this feature be added please?

(Unfinished LogSkelion script attached. It creates two Logarithmic Spirals, and Blends them, with variable results for the location of the Blend.)

The rightmost curve is the desired result.



- Brian

EDITED: 2 Oct 2014 by BEMFARMER

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
6955.2 In reply to 6955.1 
Hi Brian, there is another input to Blend, it's input index 1 and it contains a list of curve orientation records.

When Blend is run the first time the blend factory will look if factory input index 1 is empty, and if it is it will create a new list of curve orientation records starting out with the ends closest to one another being the ones blended between. When you're in the blend command if you click on one of the curves it will toggle the flip part of the curve orientation record and flip the blend to the other side. That record is then used later on with history updates so that the history calculation can know which side was used for the blend.

Unfortunately right now there is no way for a script to create its own curve orientation records, they are created internally by the blend factory on its first run through and there isn't any script accessible method to create one right now. Those are IMoiCurveOrientation objects.

So sorry right now I don't think it's possible to do what you're looking for in this case.

- 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
6955.3 In reply to 6955.1 
I guess maybe what you could do would be to make a blend factory, run .calculate on it, that should make a curve orientation list in input index 1, that then handles building the list and I think it will be possible for a script to modify an existing curve orientation list.

After the .calculate() or .update() that would go something like this:

// Grab the curve orientation list from input index 1.
var orientations = factory.getInput(1).getValue();

// This is an IMoiList which will contain 2 entries in it, each of which is a IMoICurveOrientation object.
// The IMoiCurveOrientation has 2 properties: .flipped and .seam - curve blendin will only look at the .flipped property so toggle that.

// Something like:

var orient = orientation.item(0);
orient.flipped = !orient.flipped;


Then recalculate or update again.

- 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:  bemfarmer
6955.4 In reply to 6955.3 
Thank you for the explanations Michael !

I'll try them out. I have a slight glimmer of understanding :-)

With two curves, there are 4 possible Blends, so if there is a "Toggle" button, maybe the user could toggle the 4 choices,
until the correct one comes up. (?)

Or there could be one checkbox for each curve... fliporient curve1, and fliporient curve2.


Or I'll just use the line segment between the two central points, which I have already tried out.

- Brian

So Input 0 is for the curves, (or edges)
Input 1 is for orientation, and ... etc.

I do not understand how the orientations get in there from picking curves in certain areas, but Flow is doing it too. It must be the Magic of Moi programing.

EDITED: 1 Oct 2014 by BEMFARMER

  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
6955.5 In reply to 6955.4 
Hi Brian,

> So Input 0 is for the curves, (or edges)
> Input 1 is for orientation, and ... etc.

For Blend:

Input 0 = Object list, objects to blend (either curves or edges).
Input 1 = Orientation list, determines direction flipping and also seam position for surface blend between closed edges
Input 2 = Continuity, string of 'G1', 'G2', or 'G3'
Input 3 = Bulge factor, floating point number
Input 4 = List of points for optional sync points for surface blend.
Input 5 = optional x,y,z vector for surface blend planar sections direction


> I do not understand how the orientations get in there from picking curves in certain
> areas, but Flow is doing it too. It must be the Magic of Moi programing.

If they were selected by a click and the click was near the end of the curve, it sets .flipped = true on the orientation record for that curve which means blend from the end of the curve rather than the start of it.

If they were not click selected (either window selected, select all, or done by scripting), it will test distances from endpoint to endpoint and set flipping so the minimum distance combination will be used.

This all happens inside the Blend factory when it processes objects.

- 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:  bemfarmer
6955.6 In reply to 6955.5 
It seems that each of the two curves would need to have an orientationlist , to control which end is blended ?

Would the order inside get.Input(1).getValue() be orient1, seam1, orient2, seam2 ?

What is the proper way to make the new orientlist for setInput(1, orientlist) ?

The following code does not change the blending order. G3 Blending still occurs between the closest ends of the 2 curves.

code:
    var blendfactory = moi.command.createFactory( 'blend' );

               blendfactory.setInput( 0, curvelist );
//            blendfactory.setInput( 1,  orientationlist );
               blendfactory.setInput( 2, 'G1' ); //versus 'G2' or 'G3'
               blendfactory.setInput( 3, 1.00 );
//            blendfactory.setInput( 4, pointlist );
//            blendfactory.setInput( 5, vector );

	var bCurve = blendfactory.calculate();
	var orientations = blendfactory.getInput(1).getValue();
	blendfactory.cancel();				
	var orient = orientations.item(0);
	orient.flipped = !orient.flipped;

	var seamvalue = orientations.item(1); //try to get the (un-needed) seam for the new orientlist ?
			
	var orientlist = concat(orient.flipped, seamvalue.seam); //try to make a new orientlist for the two curves ? 

				
	var blendCurve = factory( 'blend', curvelist, orientlist , 'G3', 1.18 ); //This still makes the 2 spirals.



- 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
6955.7 In reply to 6955.6 
Hi Brian,


> It seems that each of the two curves would need to have an
> orientationlist , to control which end is blended ?

There's one orientation list, and the orientation list has 2 items in its array, each item in the array is an IMoiCurveOrientation object which has 2 properties on it: .flipped and .seam.


> Would the order inside get.Input(1).getValue() be orient1, seam1, orient2, seam2 ?

factor.getInput(1).getValue() will return the list. Then there are 2 items in the list, and each of those items has a .flipped and .seam property on it. Hope that makes sense.


> The following code does not change the blending order. G3 Blending still occurs
> between the closest ends of the 2 curves.

Can you post the full .js and .htm files so I can give the whole thing a try over here and see if I can tweak it?

- 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:  bemfarmer
6955.8 In reply to 6955.7 
Hi Michael, and thank you again

Attached is the latest (work in progress) version, which still forms the two log spirals, with Blend by closest endpoints.
So I still do not have it right :-)

Blending code starts at line 111.

- Brian

 

(I previously had the central line connection working. And still have to do circular revolve, and match up tangents, so right now
only a pair of log spirals and (sometimes misplaced) blend occurs.)

EDITED: 2 Oct 2014 by BEMFARMER

  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
6955.9 In reply to 6955.8 
Hi Brian, I'll take a look into it a bit later on today 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:  bemfarmer
6955.10 In reply to 6955.9 
Thanks Michael

I'm looking into the trig/algebra.
Tangents seem to be matching up so far.

- 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
6955.11 In reply to 6955.8 
Hi Brian, try the attached version in place of the last .htm file you posted above.

Basically once you have grabbed out the orientation list and changed the one flip value in it, then you want to re-use that same orientation list that was just modified rather than trying to build a completely new one. You can't build a new one right now because scripts don't have any way to create an IMoiCurveOrientation object so you have to re-use the one that was grabbed out from the factory.

Check a diff utility to see the changes but basically don't do this:

code:
				// TRY to make a new orientations list with the name orientlist.
				var orientlist = concat(orient1.flipped, seamvalue1.seam, orient2.flipped, seamvalue2.seam ); 


That will make a list but it won't contain IMoiCurveOrientation objects in it, it will be a list with 4 items in the list: boolean, double, boolean, double. It resembles the orientation list, but the what the orientation list is here is a list of 2 CurveOrientation objects with each of those objects having 2 properties. Yes both of these constructs have 4 properties total in it, but the system is expecting CurveOrientation objects in this case and so just individual properties in the list without them actually belonging to a CurveOrientation object won't do the trick here.


So then when you do the blend, just use the orientlist that was sucked out from the factory previously like this:

code:
              var blendCurve = factory( 'blend', curvelist, orientlist , 'G3', 1.18 );



Hope this helps!

Sorry this stuff is so tricky currently, in V4 I'll be trying to make a lot more direct methods for constructing various things rather than only being able to do all creation stuff through the generic factory mechanism.

- Michael
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
6955.12 In reply to 6955.11 
Thank you very much Michael.

The BLEND now works for the center, 99% of the time. The exceptions are for 2 arms, and exponent less than 0.17, and 3 or 4 arms with
exponent even less, so I made the slider minimum for exponent to be 0.17. Lower values could still be manually entered.

Surprisingly, doing !orient#.flipped to both the curves resulted in the Tail Ends of both spirals to be blended. So it was not necessary to do !orient1.flipped
or !orient.flipped. But the second Blend does need the orientations "list".

On another note, I was occasionally able to crash Moi by trying to enter an exponent number, but failing to enter any numbers, and entering blank numbers.

Using a beautiful Moi PDF of some circular arrayed spirals, I was able to do the Math to compute the Polygon radius, for the center of circular array.
polyRadius = (Math.exp(expo * stopangle2) + Math.exp(expo * stopangle1)) / ( 2 * Math.sin( Math.PI/N.value )); Where N.value is the number of tentacles.

The "final" script does not have manual G# continuity entry, nor Bulge slider.

The spirals join without any difference in the tangents, based upon a few trials.

Default exponent is for a Golden ratio. Clicking on some commands restores to default values.

- Brian




See next post for October3_2014 version.

EDITED: 5 Oct 2014 by BEMFARMER


  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
 From:  bemfarmer
6955.13 In reply to 6955.12 
Here is the October 3, 2014 "Final Final" LogSkelion script.

The G1, G2, G3 continuity options, and the Bulge slider were borrowed and adapted from BLEND command.

- 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
 

Reply to All Reply to All