Parametric design in MoI?
 1-14  …  295-314  315-334  335-354  355-374  375-394  …  895-912

Previous
Next
 From:  Karsten (KMRQUS)
7713.335 In reply to 7713.334 
forgot to post!
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:  mkdm
7713.336 
Hi everyone!

While waiting for new versions of Max's NodeEditor,
i'm doing some experiments with PatternArray selection :

Here's my current unfinished version of the node PatternSelectArray :

code:
// PatternSelectArray
function PatternSelArray()
{
	this.addInput("In","pointarray");
	this.addInput("Start","number");
	this.addInput("Qt_Max","number");
	this.addInput("Step","number");		
	
	this.addOutput("Out","pointarray");
	this.addOutput("Elems","number");
	this.addOutput("Source","pointarray");
	
	this.properties = { mode:["Pattern + Subset", "Pattern + Subset", "Subset + Pattern"],
		pattern:"+",
		start:0,
		qt_max:-1,
		step:1};
	
}

PatternSelArray.title = "PatternSelArray";
PatternSelArray.desc = "PatternSelArray";

PatternSelArray.prototype.onExecute = function()
{
	//if (this.properties.order[0] == "By Selection") {
		
	var source = this.getInputData(0, new pointArray());
	this.properties.pattern = this.properties.pattern.trim();
	
	var usePattern = false;
	var isMixedPattern = false;
	
	// check the pattern
	if (this.properties.pattern != '') {
		// check if pattern contains valid characters
		usePattern = this.properties.pattern.match('^[+\-0-1]+$');
		
		if (usePattern) {
			// check if pattern contains only include characters (+ or 1)
			usePattern = !this.properties.pattern.match('^[+1]+$');
			
			if (usePattern) {
				// if pattern contains both include and exclude characters, then the pattrn will be used
				// otherwise it means that contains only exclude characters (- or 0), and therefore
				// the output pointarray list will be empty
				isMixedPattern = !this.properties.pattern.match('^[\-0]+$');
			}
		}
	}

	var output = new pointArray(); // init to empty list

	if (usePattern) {
		if (isMixedPattern) {
			var len = source.getLength();
			var cn = 0;
			
			for (i = 0; i < len ; i++) {
				if ( this.properties.pattern[cn] === '1' || this.properties.pattern[cn] === '+') {
							
					var source_elem = source.getElement(i);
					
					output.push(source_elem.pt.x,
						source_elem.pt.y,
						source_elem.pt.z,
						source_elem.AngleX,
						source_elem.AngleY,
						source_elem.AngleZ,
						source_elem.Size);
				}
				cn = (cn < this.properties.pattern.length-1) ? cn+1 : 0;
			}
		}
	} else {
		// elaborate the whole source pointarray
		this.properties.pattern = '';
		output = source;		
	}

	var outLength = output.getLength();
	
	this.properties.start = this.getInputData(1, this.properties.start);
	if (this.properties.start < 0) this.properties.start = 0;
	if (this.properties.start > (outLength - 1)) this.properties.start = (outLength - 1);

	this.properties.qt_max = this.getInputData(2, this.properties.qt_max);
	if ((this.properties.qt_max < 0) || (this.properties.qt_max > outLength)) this.properties.qt_max = outLength;
	
	this.properties.step = this.getInputData(3, this.properties.step);
	if (this.properties.step <= 0) this.properties.step = 1;
	if (this.properties.step > outLength) this.properties.step = outLength;
	
	// generate the final pointarray list
	var outputFinal = new pointArray();
		
	for (i = this.properties.start, cont = 0; i < outLength && cont < this.properties.qt_max; i += this.properties.step, cont++) {
		var source_elem = output.getElement(i);
		
		outputFinal.push(source_elem.pt.x,
			source_elem.pt.y,
			source_elem.pt.z,
			source_elem.AngleX,
			source_elem.AngleY,
			source_elem.AngleZ,
			source_elem.Size);
	}
	
	output = null;
	
	this.setOutputData(0, outputFinal);
	this.setOutputData(1, outputFinal.getLength());
	this.setOutputData(2, source);
	
	this.outputs[1].label = "Elems(" + outputFinal.getLength() + ")";
}

LiteGraph.registerNodeType("Arrays/PatternSelArray", PatternSelArray);


The inputs and outputs are :

1 - In : the source PointArray
2 - pattern : the filter pattern string : 1 or + pick the element, 0 or - skip the element
Example "1001" or "+--+"

3 - Start : the first element index of the resulting array after the pattern filtering
4 - Qt_Max : Max quantity of elements present in the final output array
5 - Step : The step used while iterate over the patterned array

6 - Out : the final array
7 - Elems : the number of elements present in the final array
8 - Source : The initial source PointArray


Actually the node works in this way :

1) The pattern is applied to the source array
2) Start , Qt_Max and Step are used to iterate over the patterned PointArray

Actually the property "mode" is not used, but when activated,
will determine the order of the used logic :
First do Pattern operation and then Iterates
or
First Iterates and then do Pattern operation


Nice evening to all,


Marco.
  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:  James (JFH)
7713.337 In reply to 7713.334 
Hi Karsten

Great work!

I am totally onboard with your wrapping function for additional outputs proposal.
However could it be achieved with a two tiered menu as shown?
& removed in a similar method to the removal of additional inputs

This way the info panel is not further crowded with non-dynamic elements.

Just a thought
-James

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:  Karsten (KMRQUS)
7713.338 In reply to 7713.337 
Hello James,

I had the same idea also, but I could not get it to run:-( I don't understand the core stuff already. Every time I have a short look in it, I have to google for hours. Nevertheless I am still learning. The other reason why I switched back to a selection of the function in the info panel was, that I don't know a good way for multiple outputs (not implemented, but I think possible this way) So the code is only an experiment to explain the idea, not a real solution. I hope Max will implement such a feature. It would help to extend the nodeeditor with such basic functions in a simple way.

Have a nice day
Karsten
  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:  James (JFH)
7713.339 In reply to 7713.338 
Karsten/Max

I also think it would be useful to introduce a radio button associated to inputs as shown.
In the case of array nodes, range inputs could all be activated with cascade menu directly on node
or individually in info panel. It would be immediately apparent in the info panel which field has an
active input and which can be activated/deactivated if need be.

The simple remains simple; & the complex is possible

-James

EDITED: 6 May 2019 by JFH

  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:  mkdm
7713.340 In reply to 7713.339 
Hi James,

i agree with you.

It would be very useful having the possibility to use a bunch of classic input controls inside nodes,
like radiobuttons and checkboxes.

In my garbage time i'm testing some javascript code that goes in that direction.

But i think that until Max will not release a new updated version of Nodeeditor, all these idea are only valid as a javascript developing practise...

Nice day,

Marco.
  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:  mkdm
7713.341 
Hi everyone!

here's the new code of my "PatternSelArray" and "ArrayReplicator".

The attached pictures show a simple example.

If you find bugs and errors, please, let me know...

Nice evening to all,

Marco (mkdm)

code:
// PatternSelectArray
function PatternSelArray()
{	
	this.size = [160,70];
	this.minsize = [160,70];
	
	this.addInput("In","pointarray");
	this.addInput("Start_Idx","number");
	this.addInput("Qt_Max","number");
	this.addInput("Step","number");		
	
	this.addOutput("Out","pointarray");
	this.addOutput("Elems","number");
	this.addOutput("Source","pointarray");
	
	this.properties = { mode:["Pattern + Subset", "Pattern + Subset", "Subset + Pattern"],
		pattern:"",
		start_idx:0,
		qt_max:-1,
		step:1 };
	
}

PatternSelArray.title = "PatternSelArray";
PatternSelArray.desc = "PatternSelArray";

PatternSelArray.prototype.onExecute = function()
{		
	/*
		source = the source array
		start_idx = index of the first element to pick
		numMaxElem = max number of elements that will be present in the resulting array
		step = step amount for the for..loop
	*/
	var getPointArraySection = function(source, start_idx, numMaxElem, step) {

		var result = new pointArray();
		
		if (source) {
			var sourceLength = source.getLength();
			for (i = start_idx, cont = 0; i < sourceLength && cont < numMaxElem; i += step, cont++) {
				var source_elem = source.getElement(i);
				
				result.push(source_elem.pt.x,
					source_elem.pt.y,
					source_elem.pt.z,
					source_elem.AngleX,
					source_elem.AngleY,
					source_elem.AngleZ,
					source_elem.Size);
			}
		}
		return result;
	}

	/*
		source = the source array
		pattern = string that define the selection pattern
			1 or + = pick element
			0 or - = skip element
	*/	
	var applyPatternToPointArray = function(source, pattern)
	{
		function ResultObj(pattern) {
			this.array = new pointArray();
			this.pattern = pattern;
		}

		var usePattern = false;
		var isMixedPattern = false;			
		var result = new ResultObj(pattern);
		
		if (pattern) {
			result.pattern = pattern.trim();
			
			// check the pattern
			if (result.pattern != '') {
				// check if pattern contains valid characters
				usePattern = result.pattern.match('^[+\-0-1]+$');
				
				if (usePattern) {
					// check if pattern contains only include characters (+ or 1)
					usePattern = !result.pattern.match('^[+1]+$');
					
					if (usePattern) {
						// if pattern contains both include and exclude characters, then the pattrn will be used
						// otherwise it means that contains only exclude characters (- or 0), and therefore
						// the output pointarray list will be empty
						isMixedPattern = !result.pattern.match('^[\-0]+$');
					}
				}
			}
		}

		if (usePattern) {
			if (isMixedPattern) {
				var len = source.getLength();
				var patLen = result.pattern.length;
				var cn = 0;
				
				for (i = 0; i < len ; i++) {
					if ( result.pattern[cn] === '1' || result.pattern[cn] === '+') {
								
						var source_elem = source.getElement(i);
						
						result.array.push(source_elem.pt.x,
							source_elem.pt.y,
							source_elem.pt.z,
							source_elem.AngleX,
							source_elem.AngleY,
							source_elem.AngleZ,
							source_elem.Size);
					}
					cn = (cn < (patLen - 1)) ? (cn + 1) : 0;
				}
			}
		} else {
			// elaborate the whole source pointarray
			result.pattern = '';
			result.array = source;		
		}

		return result;
	}

	// Business logic
	var source = this.getInputData(0, new pointArray());
	
	this.properties.start_idx = this.getInputData(1, this.properties.start_idx);
	this.properties.qt_max = this.getInputData(2, this.properties.qt_max);
	this.properties.step = this.getInputData(3, this.properties.step);

	if (this.properties.step <= 0) this.properties.step = 1;
	
	var patternedArray;
	var outputIntermediate;
	var outIntermLength;
	
	if (this.properties.mode[0] == "Pattern + Subset") {
		patternedArray = applyPatternToPointArray(source, this.properties.pattern);		
		outputIntermediate = patternedArray.array;		
		outIntermLength = outputIntermediate.getLength();
	} else {
		outputIntermediate = source;
		outIntermLength = source.getLength();
	}

	if ((this.properties.start_idx < 0) || (this.properties.start_idx > (outIntermLength - 1))) this.properties.start_idx = 0;
	
	if (this.properties.qt_max < 0) this.properties.qt_max = outIntermLength;
	
	outputIntermediate = getPointArraySection(outputIntermediate,
						this.properties.start_idx,
						this.properties.qt_max,
						this.properties.step);

	if (this.properties.mode[0] == "Subset + Pattern") {
		patternedArray = applyPatternToPointArray(outputIntermediate, this.properties.pattern);
		
		outputIntermediate = patternedArray.array;
		
		outIntermLength = outputIntermediate.getLength();
	}
						
	this.properties.pattern = patternedArray.pattern;
	patternedArray = null;
	
	this.outputs[0].label = "Out (" + outputIntermediate.getLength() + ")";
	this.outputs[1].label = "Elems (" + outputIntermediate.getLength() + ")";
	this.inputs[0].label = "In (" + source.getLength() + ")";
	
	this.setOutputData(0, outputIntermediate);
	this.setOutputData(1, outputIntermediate.getLength());
	this.setOutputData(2, source);
	
}

LiteGraph.registerNodeType("Arrays/PatternSelArray", PatternSelArray);

// ArrayReplicator
function ArrayReplicator()
{
	this.labels = "abcdef";
	this.size = [140,40];
	this.minsize = [140,40];

	this.internal = {a:1, b:1};
	
	this.addInput("In","pointarray");
	
}

ArrayReplicator.title = "Array Replicator";
ArrayReplicator.desc = "Array Replicator";

ArrayReplicator.prototype.onGetOutputs = function()
{
	var list = [];
	for ( var i = 0; i<this.labels.length; i++ )
	{
		var out = this.labels.charAt(i);
		if ( !(out in this.internal)) { list.push([this.labels.charAt(i),"pointarray", {locked:true}]); break; }
	}
	return list;
}

ArrayReplicator.prototype.onOutputAdded = function(out)
{
	this.internal[out.name] = 1;
	for ( var i in this.outputs ) this.outputs[i].locked = true;
	if (i>1) this.outputs[i].locked = false;
}

ArrayReplicator.prototype.onOutputRemoved = function(slot, name)
{
	if ( this.internal[name] ) delete this.internal[name];
	for ( var i in this.outputs ) this.outputs[i].locked = true;
	if ( this.outputs.length > 2 )this.outputs[i].locked = false;
}

ArrayReplicator.prototype.onAdded = function()
{
	for ( var i = 0; i<this.labels.length; i++ ) if ( this.internal[this.labels.charAt(i)] && this.outputs.length == i ) this.addOutput(this.labels.charAt(i), "pointarray");
	this.setDirtyCanvas(true);
}

ArrayReplicator.prototype.onExecute = function()
{
	var source = this.getInputData(0, new pointArray());

	this.inputs[0].label = "In (" + source.getLength() + ")";
	
	for ( var i = 0; i<this.outputs.length; i++)
	{
		this.setOutputData(i, source);
	}	
}

LiteGraph.registerNodeType("Arrays/ArrayReplicator", ArrayReplicator);
Image Attachments:
Size: 155.3 KB, Downloaded: 89 times, Dimensions: 1522x822px
Size: 1.1 MB, Downloaded: 113 times, Dimensions: 1918x1035px
  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:  Frenchy Pilou (PILOU)
7713.342 
Cool thing to have all possible nodes in one wink!
---
Pilou
Is beautiful that please without concept!
My Gallery
  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:  Max Smirnov (SMIRNOV)
7713.343 
Hi guys!
Sorry, I didn't write a line of code this week. I was so busy at work.
Maybe next week I'll continue developing of this project.

Marco, this ArrayReplicator looks good, but it will be better if we use a multiple output connections. ;)

EDITED: 7 Mar 2022 by SMIRNOV

  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:  mkdm
7713.344 In reply to 7713.343 
Hi Max,

> Marco, this ArrayReplicator looks good, but it will be better if we use a multiple output connections. ;)

I totally agree with you!

While waiting your next NodeEditor release, i'm still playing with array nodes, and after "PatternSelArray" and "ArrayReplicator",
i'm thinking to write :
- "ArrayShuffler" : shuffle the elements inside one array
- "ArrayInspector" : it should output to a textarea, the numeric values of all array elements. Useful for debugging purposes.
- "ArrayExporter" : it should output to a file, the numeric values of all array elements.
- "RandomArray" : In should generate random points inside a 3d cube area.

These ideas are nothing more then a funny and simple javascript programming practice for me,
simple ideas that you might find interesting.

Nice night to all,

Marco.
  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:  Karsten (KMRQUS)
7713.345 In reply to 7713.343 
Hello Max,

the main thing , you are well . I enjoy the break:-)

Have a nice weekend
Karsten
  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
7713.346 
Here is a lighter color for the Canvas.
Under nodeeditor/core/imgs, save the original grid.png, and replace it with the lighter grid.png.

The colors of the original grid was inverted. This was done with Gimp2, or with Greenfish Icon Editor Pro (GFIE).
The lighter colors were swapped with GFIE. GFIE does not compress the PNG, so PNGGauntlet was used to shrink the PNG file size.

A button to select the grid colors might be nice, as well as an even lighter grid for printing.

- Brian (Grid.png removed as it is no longer used.)


EDITED: 18 Mar 2017 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:  bemfarmer
7713.347 In reply to 7713.346 
I made an even lighter grid, but the cursor is almost invisible. :-(

The few icon/png editors I've tried have been difficult to use as well.

- 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:  bemfarmer
7713.348 In reply to 7713.346 
. So how do I delete a message?

- 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
7713.349 In reply to 7713.348 
Hi Brian,

re:
> . So how do I delete a message?

In the bottom right corner of a message there's a "more" link and if you click it a menu will pop out with a "Delete" link on it.

If that doesn't work, just give a link to the message you want to delete and I can do it for you too.

- 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
7713.350 In reply to 7713.349 
Thank you Michael.
(I've been unable to delete from the edit window.)
  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:  Karsten (KMRQUS)
7713.351 In reply to 7713.348 
Hello Brian,
dont't delete the message. The cursor can be customized with e.g. Gimp. Take a cursor example (also png) from this thread and change form and color and share it also, please.

Have a nice day
Karsten
  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
7713.352 In reply to 7713.351 
To switch to an arrow cursor, locate the litegraph.css file under nodeeditor\css\, and change "crosshair" to "default", without the quote marks.
(Line 4)

https://css-tricks.com/almanac/properties/c/cursor/

Attached is a lighter grid.png replacement for the canvas. In the canvas display it still seems to be relatively dark.

The Wand selector of the Greenfish Icon editor cannot distinguish between two different tints and/or tones and/or shades, which are nearly the same .
This makes it hard to select the proper areas of the grid.png for editing.

The Wand selector of the IcoFX2 icon editor can so distinguish, but does not do Hex colors. Setting one of the two colors of Grid.png to a very different color allows the .png to be edited in the Greenfish Icon editor, which does do Hex colors.

- Brian

Grid.png removed as no longer needed.

EDITED: 18 Mar 2017 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:  mkdm
7713.353 
Hi everyone,

While waiting the next official NodeEditor release by Max, here's my the first stable version (0.1) of some nodes i wrote :

N.B. these nodes requires the latest v.0.65b version of Max's NodeEditor.

- "PatternSelArray" : returns a PointArray, made by a patterned+subset selection of the input PointArray's element

- "ArrayShuffler" : returns a PointArray, by shuffling the elements inside the input PointArray (RMB -> Update : generate a new random shuffle)
For example, it may be useful to create objects like ball of wool.

- "ArrayFlipper" : returns a PointArray, made by flipping the elements of the input PointArray

- "ArrayLogger" : Outputs to a textarea the content of the input PointArray. It's useful for debugging.
You can copy/paste the textarea's content, to a text editor, in order to better view all the text.
Every line of text contains the full data of each point present in the input PointArray, separated by a single space :
X Y Z AngleX AngleY AngleZ Size

- "ArrayReplicator" : Replicates the input PointArray. It may be useful only in order to keep the graph cleaner.

In order to use these new nodes, follow these steps :

1) copy the "arraysExt.js" file into the "nodes" folder of NodeEditor
2) copy the "litegraphExt.js" file into the "core" folder of NodeEditor
3) add these lines of code to the "index.html" file of NodeEditor

code:
<script type="text/javascript" src="core/litegraphExt.js"></script>
<script type="text/javascript" src="nodes/arraysExt.js"></script>


I hope that you will find these nodes useful.

Please, let me know if you will find bugs.

Nice day to all!

Marco (mkdm)

EDITED: 30 May 2016 by MKDM


Image Attachments:
Size: 75.3 KB, Downloaded: 49 times, Dimensions: 968x704px
Size: 176 KB, Downloaded: 96 times, Dimensions: 1721x971px
Size: 2.1 MB, Downloaded: 87 times, Dimensions: 1920x1034px
Size: 155.6 KB, Downloaded: 58 times, Dimensions: 1720x967px
  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:  Karsten (KMRQUS)
7713.354 In reply to 7713.353 
Hello Marco,

Thank You very much for sharing. I have tested some nodes and for now, everything works fine. Especially the ArrayLogger will help to debug while programming and also while using the nodeeditor. I'm very curious what's comming next.

Have a nice day
Karsten
  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-14  …  275-294  295-314  315-334  335-354  355-374  375-394  395-414  …  895-912