MoI discussion forum
MoI discussion forum

Full Version: Utility Scripts for analysis : FilterCurvesByLength

Show messages: All  1-2  3-20

From: mkdm
30 Sep 2017   [#3]
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)
From: mkdm
30 Sep 2017   [#4] In reply to [#2]
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)
From: mkdm
2 Oct 2017   [#5] In reply to [#2]
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)
From: Michael Gibson
2 Oct 2017   [#6] In reply to [#5]
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
From: mkdm
2 Oct 2017   [#7] In reply to [#6]
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.
From: Michael Gibson
2 Oct 2017   [#8] In reply to [#7]
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
From: wastzzz
3 Oct 2017   [#9] In reply to [#1]
Please make it work with float values too..
It is useful to me.

Thanks
M.
From: Michael Gibson
3 Oct 2017   [#10] In reply to [#7]
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
From: mkdm
3 Oct 2017   [#11] In reply to [#9]
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!
From: mkdm
3 Oct 2017   [#12] In reply to [#8]
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!
From: mkdm
3 Oct 2017   [#13] In reply to [#8]
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!
From: mkdm
5 Oct 2017   [#14]
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.
From: Frenchy Pilou (PILOU)
5 Oct 2017   [#15]
The store's case is like a "Copy" inside the ClipBoard ?

Selection(s) given by the slider can be Copied, Moved, Erased ?
From: mkdm
5 Oct 2017   [#16] In reply to [#15]
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)
From: Frenchy Pilou (PILOU)
5 Oct 2017   [#17] In reply to [#16]
<< 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.
From: mkdm
5 Oct 2017   [#18]
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!
From: mkdm
11 Feb 2018   [#19]
Hi everyone!

The very interesting new thread by Brian "Curve Explorer, MoI4 only" (at http://moi3d.com/forum/index.php?webtag=MOI&msg=8818.1) reminded me that many months ago I have started to code a never finished new custom command dedicated especially to 2D workflows : "FilterCurvesByLength"

I recovered now the latest alpha version that I was coding months ago.
It was never finished but was at a very good stage, so now for the moment I want to publish here a demo of its actual state and as soon as I can, I want to clean up its code a little bit and publish the latest alpha.

Of course anyone will be free to use it for whatever reason or inspiration because I don't know if I will have time to finish its coding.

This little project was only a first attempt to create a very complex and universal "Selection Master", a plugin that I have in mind for a very long time,
dedicated to filtering almost everything in Moi, based on various rules and inputs : mass of solid, length of curves, area of surfaces, and so on....

But I think I was a little bit too "upbeat" because I think that actually this kind of plugin goes beyond my possibilities :)

Anyway...it's an idea that I wanted to share with you.

Maybe there's someone that want to put his hands on keyboard and start to coding :)

But... cut to the chase! This is the demo of the current version of "FilterCurvesByLength".

During next days I will post also the code.

Here's a demo video (114 Mb) : http://take.ms/mDpcW

And this is a screenshot.



The bottom section of the UI is currently reserved to two custom scrollable listview showing many statistic data of the current filtering.
At the time of my latest coding of the command, I planned also to allow the user to save the results of the filtering in a txt file in order to read it later.
Also I planned to give the user the chance to save "filtering configs" so instead configuring every time a combination of filters, the user can load the desired config.

All idea that I never implemented :)

Ciao!

Marco (mkdm)
From: mkdm
14 Feb 2018   [#20]
Hi everyone!

This is the zip file of my "FilterCurvesByLength" custom command, alpha version v. 0.5, Oct 07 2017.

http://take.ms/rwm9Q

It works on both V3 and V4.

For V3 and V4 you can unzip the archive and copy the two files into the standard "commands" folder of Moi

For V4 you can decide to copy the two files into the new C:\Users\<user>\AppData\Roaming\Moi\commands

To use this custom command you have to select at least 1 edge or curve.
It works on both kind of entities.

Keep in mind one thing before playing with this command.

As you can see, its UI needs a minimum amount of room to be shown properly, on my default Windows 10 config with default fonts, this room is "21em".

This size is related to the width of the "flex_vbox" into the file "C:\Program Files\MoI 4.0 beta Feb-9-2018\ui\SidePane.htm"







This custom command has almost nothing special as I said, and its Javascript code has no fancy in it.

It's already pretty fast but it could be optimized much more.

Anyway, besides its usefulness (I've written this plugin with 2D workflows in mind) it has at least one special feature :)
If you will test it you will see.

As you can see its UI has two main sliders, "Min" an "Max", referring to the length that we want to use as main "filter"

Well, the tricky thing is that the lower and upper limit of both sliders are automatically calculated when the command starts, based on the selected entities.

That's all.

Keep in mind that I never finished the coding of this plugin and it has for sure some hidden bug.
But for what I've tested so far it worked very well.

Enjoy!

Show messages: All  1-2  3-20