Full Version: Utility Scripts for analysis : FilterCurvesByLength

From: mkdm [#1]
 30 Sep
To: ALL

Hi Michael and everyone.

After a long conversation with Michael, started at http://moi3d.com/forum/index.php?webtag=MOI&msg=8604.4,
about the chance and the way of trying to write some script for curves and surfaces analysis (altougth the latter is much more difficult),
and the way to do that keeping a decent execution time, even for a decent amount of objects (let's say more than 10000),
yesterday I've written this little script.

This script, starting from the selected curves, filter them by their length and automatically select them.

Please keep in mind this consideration when using it :

1) It is the very first alpha version

2) For the moment it processes only curves. As you can see in the picture, I've already prepared the UI to manage other kind of filtering,
but for the moment, these flags are not active.

3) The code itself is very simple and it has not particular optimization.
I only executes a simple pre-calculation of the length of the selected curves and stores the data into a "proxy" array,
so in this way the script execution is much faster in realtime, when you drag the sliders.
Later on I want to add at least a sort and binary search of the array.

4) it seem that only sliders works.
I mean that if you enter a value in the numeric fields and press the enter key, nothing happens.
I don't know why this happens.
If someone knows how to manage the manual numeric input for fields please tell me :)


I hope that this is a very first script of a series of script that I wish to write for simple analysis purposes (curve length and surface area).

This is the script file, place it into "Commands" folder : http://take.ms/Ol5BM

This is a brief demo video : http://take.ms/0PMQ9

As you can see with my pc (i7-7700K 4.2-4.5 Ghz 32GB Ram DD4 3000 and Gtx 1080 Ti) the performance in realtime is very satisfying.

The scene has 30.000 control point curves.

This is the screen capture :



Bye!

Reply


From: Michael Gibson [#2]
 30 Sep
To: ALL

Hi Marco,

re:
> I mean that if you enter a value in the numeric fields and press the enter key, nothing happens.
> I don't know why this happens.
> If someone knows how to manage the manual numeric input for fields please tell me :)

So the way it works is that if a numeric field has a id="" attribute set on it, then when the value is changed it will generate a UI event of that same name. So to handle that in your event loop in the .js file, look for e == 'minlen' or e == 'maxlen' and trigger an update when you see those events.

Another thing you could try is to remove the call to setInterval and instead put handlers for each slider for onmousemovevaluechange="" if you want to run something on every mouse move of the slider rather than just when the mouse is released.

- Michael

Reply


From: mkdm [#3]
 30 Sep
To: ALL

This is for "Marbleman".

I tried to reply to your PM but I get "MARBLEMAN has opted out of receiving personal messages".

Please don't send me PM if you don't want to receive PM :)

Anyway...to reply to your question.

"commands and script history" that you can see in my videos is something that I wrote on my own to personalize my Moi.

I think that when I will find a decent amount of free time, I will post my entire Moi folder, as is (with some cleanup),
with all UI plugins that I wrote. One of them is "commands and script history".

Bye.

Marco (mkdm)

Reply


From: mkdm [#4]
 30 Sep
To: ALL

Hi Michael.

@You : "...So to handle that in your event loop in the .js file, look for e == 'minlen' or e == 'maxlen' and trigger an update when you see those events...
Another thing you could try is to remove the call to setInterval and instead put handlers for each slider for onmousemovevaluechange=""..."

Done!

Thanks a lot for suggestion.

Now the script is a little bit faster!

Here's the updated alpha version : http://take.ms/j9tG7

(The checkboxes are still inactive.)

Cheers.

Marco (mkdm)

Reply


From: mkdm [#5]
 2 Oct
To: ALL

Hi Michael.

I'm improving my script and I want to make it more "dynamic" and I need to do this thing :

Into the HTML code of the command's page I have this code :

code:
...
<tr>
    <td colspan=3 id="maxlensliderContainer"><moi:Slider id="maxlenslider" min="0" max="200" style="width:100%" onmousemovevaluechange="doFilter();"/></td>
</tr>
<tr>
    <td colspan=3 id="maxlenInputContainer"><moi:DistanceInput id="maxlen" style="width:6em;" default="1" binding="maxlenslider.value = this.value"/></td>
</tr>


Well. Now I need to dynamycally change the max="200" to assign it a value that I calculated inside the "function init() {...}".

I have tried many ways but nothing worked.

For example I tried something like this :

code:
...
		function renderPage() {
			maxLengthValue = 20; // I put here this statements only for example. maxLengthValue is calculated inside function init() {...}
			
			document.getElementById("maxlensliderContainer").innerHTML =
				"<moi:Slider id=\"maxlenslider\" min=\"0\" max=\"" + maxLengthValue + "\" style=\"width:100%\" onmousemovevaluechange=\"doFilter();\"/>";			
			
			return true;
		}
	</script>
</head>
<body onload="renderPage();" class="commandbody">


It seems that after executing that code the binding between the slider and the numeric input field (id="maxlen") doesn't work anymore.
(Assuming that my code at least changes in the correct way the "max=200" attribute of the slider...)

How can I do ?

Thanks for help!

I stay tuned.

Marco (mkdm)

Reply


From: Michael Gibson [#6]
 2 Oct
To: ALL

Hi Marco, so unfortunately the slider control does not currently expose the min and max values as individual properties that can be changed after parsing, they are only initialized when the control is initialized. So yes you would need to create an entire slider at once with your desired value like you're doing there.

Bindings are also only initialized after the initial document parsing pass is complete - I'd guess what is happening is when the input control's binding is parsed the slider doesn't exist yet.

One thing you might try for your case here is to initialize the slider earlier - instead of triggering it in an onload="" handler, declare a <script></script> block at the bottom of the <body> which should then run the code contained in it before the document ready event triggers and so I'd think would be set up before binders are initialized.

Another thing you could do would be to take out the binder and instead handle the connection between the 2 controls by onvaluechange="" event handlers on each element.

- Michael

Reply


From: mkdm [#7]
 2 Oct
To: ALL

Hi Michael.

I'm trying to follow your suggestion but...things doesn't work.

Maybe I am misinterpreting what you wrote about sliders.

@You : "...they are only initialized when the control is initialized. So yes you would need to create an entire slider at once with your desired value like you're doing there..."

But...I'm trying this :

code:
<body class="commandbody">
...
...
<td colspan=3 id="minlensliderContainer">
	<script type="text/javascript">
		document.write("<moi:Slider id=\"minlenslider\" min=\"0\" max=\"" + wholeMaxLength + "\" style=\"width:100%\" onmousemovevaluechange=\"doFilter();\"/>");
	</script>
</td>
...
...


the problem is that I suppose this code is executed on the page load when I still haven't calculated the variable "wholeMaxLength", and its value is only a default.

But you write "...So yes you would need to create an entire slider at once with your desired value like you're doing there..."

But, again, the problem is that at load time, when the slider is rendered, I still don't have the correct value for that variable,
because I will calculate it into the "function init() {......"

I'm in a maze :)

What can I do ?

I have also thought a possible but complex solution, and I don't know if is it feasible.

That's my idea :

1) The crucial point is that I need calculate the value to assign to the attribute "max" of the slider, BEFORE the slider will be rendered

2) Now, I thought to break in two, the command that I'm writing (FilterCurvesByLength).

3) The first part will have no UI and only JS code that should calculate the value of the variable

4) Once the calculation is complete, I might redirect to the second part of the script, that contains the complete UI,
using something like "window.location.replace" or "window.location.href = ...",
passing to the HTML page the calculated variable with URL parameter.

5) in the receiving page I will capture the URL parameter hoping that this operation could be done BEFORE page rendering.


But, I don't know if these are only wrong considerations....

I really don't know how to solve this problem.

Any further aid will be much appreciated :)

Thanks.

Reply


From: Michael Gibson [#8]
 2 Oct
To: ALL

Hi Marco, so yeah it sounds like you need to call your init() function earlier than you're doing it currently. You can do that by taking it out of where you're currently calling it from and instead call it directly below the function like this:

code:
	<head>
		<script>
			function init()
			{
				<.....>
			}
			
			init();
		</script>
	</head>


That should then run it before you need it in document.write() below. But if your init() function has some parts where it's also filling in UI controls, split that part into a second init function and you can then call that second one in onload="" or wherever you're doing it currently. It shouldn't be necessary to make a second page I don't think, just split your initialization into 2 functions and call one earlier in the page load than is happening currently.

- Michael

Reply


From: wastzzz [#9]
 3 Oct
To: ALL

Please make it work with float values too..
It is useful to me.

Thanks
M.

Reply


From: Michael Gibson [#10]
 3 Oct
To: ALL

Hi Marco, to make it work for any distance value instead of integers only you can use a <moi:DistanceInput> input field instead of a <moi:UnsignedIntegerInput> .

The <moi:DistanceInput> will allow floating point values and will automatically get a unit system label (like mm or cm, etc..) after it.

- Michael

Reply


From: mkdm [#11]
 3 Oct
To: ALL

Hi wastzzz.

@You : "...Please make it work with float values too...."

I already did it.

You can grab an updated alpha version at : http://moi3d.com/forum/index.php?webtag=MOI&msg=8608.4

I'm still working on it (late at night) to improve it with some other interesting features, (you will see...) and to speed it up but for the moment
that updated alpha is working ok for what I've tested so far.

Until I update the code with dynamically generated "Slider"'s range, if you need, you can change the range of the slider, here :

code:
<body class="commandbody">
	...
	<div id="InputContainer" class="commandoptions">
		<table style="width:100%; text-align:center;">
			...
			<tr>
				<td colspan=3><moi:Slider id="minlenslider" min="1" max="2000" .../></td>
			</tr>
			...
			<tr>
				<td  colspan=3><moi:Slider id="maxlenslider" min="1" max="2000" .../></td>
			</tr>
	...


Stay tuned!

Ciao!

Reply


From: mkdm [#12]
 3 Oct
To: ALL

Hi Michael!

Thank you very much for your suggestion!

ASAP I'm going to try what you told me.

Also, thanks for "<moi:DistanceInput>". I already did it.

Have a nice day!

Reply


From: mkdm [#13]
 3 Oct
To: ALL

Hi Michael end everyone.

Michael...your suggestion worked very well!!! Thanks a lot!!

I've done FilterCurvesByLength v. 0.3 beta!

Now I don't have time to explain all features and possible way of use my latest script,
but for the moment this is a screen capture of its UI :



Later I will post some video demostration.


Ciao!

Reply


From: mkdm [#14]
 5 Oct
To: ALL

Hi Michael and everyone.

...Almost done !!!

This is the preview of my "FilterCurvesByLength" v. 0.4 beta.

It runs decent fast also with 50K-80K curves and edges. tested both with my laptop i7-4790K and Nvdia Quadro K3100M and my
PC deskotp i7-7700K with Gtx 1080 Ti.

For the moment I only have the time to post a brief demo video.

Please watch it at : http://take.ms/a7xuM




I only have to optimize the Js code a little bit.

ASAP I'm going to post the new version of the script.

Bye.

Reply


From: Frenchy Pilou (PILOU) [#15]
 5 Oct
To: ALL

The store's case is like a "Copy" inside the ClipBoard ?

Selection(s) given by the slider can be Copied, Moved, Erased ?

Reply


From: mkdm [#16]
 5 Oct
To: ALL

Hi Pilou.

@You : "...The store's case is like a "Copy" inside the ClipBoard ?..."

This is a surprise !
No...in all seriousness, I have already planned to write a brand new plugin : "SelectionMaster " !!

"SelectionMaster" will be a very useful tool. You will see....

@You : "...Selection(s) given by the slider can be Copied, Moved, Erased ?..."

I'm sorry but I didn't understand this question :)

The main purpose of "FilterCurvesByLength" is to give the ability to SELECT curves and edges based on their length.
All it does is to produce a selection of objects.
What you do later with that selected curves/edges is up to you.

Anyway, I'v already planned to add the chance to export the filtering information to a txt file :
"Shortest, longest, amount of filtered curves, etc..."

Stay tuned!

Ciao.

Marco (mkdm)

Reply


From: Frenchy Pilou (PILOU) [#17]
 5 Oct
To: ALL

<< I'm sorry but I didn't understand this question :)
= Can we use the the selection for anything?

so you give the answer! :)

<< The main purpose of "FilterCurvesByLength" is to give the ability to SELECT curves and edges based on their length.

Reply


From: mkdm [#18]
 5 Oct
To: ALL

Hi everyone.

Before upload the new version of the script, here's another use case : remove holes from surface

This is only a simple example.

Here's the video : http://take.ms/sDO3h



Bye!

Reply


Reply to All

Back to thread list | Login

© 2017 Project Beehive Forum