Cloning a viewer material - autodesk-forge

I want to override the color of a component in the viewer, in order to conserve the same rendering effect than other components I would like to clone an existing material and simply modify the color of the clone.
I can change the color of an existing material as follow:
var renderProxy =
viewer.impl.getRenderProxy(
model, fragIds[0])
renderProxy.material.setHex(0xFF0000)
This affects all other components in the model which are using that material, which is not the desired result.
For that purpose I would like to clone material, modify it and affect the new material to a specific component. Invoking the material.clone() method is working:
var newMat = renderProxy.material.clone()
newMat.setHex(0xFF0000)
But the new material will loose all the specific properties that makes it look nice by the renderer.
So my question "is there a way to -easily- clone a viewer material without writing the cloning code for each property"?

You will need to clone the 'prism' material, rather than the 3js phong-material.
Start with this repo: https://github.com/wallabyway/fusion-chair-configurator
as an example, to create a 'metal' material, use these two lines of code (and copy the initPaint() function).
https://github.com/wallabyway/fusion-chair-configurator/blob/c6d5bd575cdf40194c9fbdd1c5f9bb27c70b356e/docs/js/app.js#L107-L108
The szPrism json string, contains lots of parameters. Prism materials are rather complex, but you can find out more about what these parameters do by understanding this article for the Autodesk Cloud Render ART help page (the real-time renderer built inside Revit2019, Fusion360, etc)...
http://help.autodesk.com/view/ARENDERING/ENU/?guid=GUID-49345267-CE6A-4006-BB58-5BEAFD8B0D0E
Try experimenting with Fusion360's 'render' mode. Start by opening 'appearance' and creating some custom materials. You can modify their parameters in real-time to better understand what they do and get the effect you are looking for.
Here is a tutorial video on Fusion360 custom materials: https://www.youtube.com/watch?v=D9AS5rQhtPo
Let me know if that helps.

Related

Import Shapes of Custom Library from Draw.io in mxGraph

I'm currently working with the mxGraph library in javascript and I'm trying to create my own shapes in draw.io, to export them, then to reuse them as much as I want in my own program using the mxGraph library.
So far, I have tried to create a custom library, which contains all my shapes. I have exported it in XML which gives me a half-encoded XML file. Then, I'd like to import that mxLibrary in my own app so I can reuse these shapes for creating my own diagrams. I have no idea how to deal with that XML file.
I have also tried taking the XML from Extras -> Edit Diagram and reimport it with the codec, then with mxGraph#addCells but the shapes aren't grouped anymore, and I can't seem to find how to clone them.
My goal would literally to have my list of shapes/cells somewhere, which I can reuse whenever I want.
If this is not possible, how may I do that instead? I have also looked up how to create my own shapes (with redrawPath and the style thing), but it looks really long and boring.
Here's an example of what the XML looks like. The shape is a simple double square.
<mxlibrary>[{"xml":"xVNBbsIwEHyN78EugjOhcOqpLzDJgi05XstZSPJ7trFbiAqCqpV6sLQ7O2N7xrJQZdNvow7mDWtwQr0KVUZESlXTl+CckIWthVoLKQteQm7uTGfjtAg6gqdnBDIJTtodISEJaGlwGThEPIZMg0jQT46q0HuoSO8+6cX3K4zUfP4WsAGKA1M6W5NJjGVWGbAHQ1NMt/keX8qLHy6ypdv21GN7nbEE70FXH33HDyHUylDDO65nXOo2sD1u9rYH3nV1N4lrx/LfHL/8veO9da5Eh5Exjx5+GUIWzJNgmHRXAS1uBLT4eUDcXn7TOJt8tjM=","w":80,"h":80,"aspect":"fixed","title":"custom_shape_1"}]</mxlibrary>
Thank you in advance!
There are 2 ways I know, to do it, depending on your needs.
Embed draw.IO as an iframe in your app, and create a plugin that adds your own palette of icon on the side bar. you can watch the p1 plugin code, and replicate it plugin list in draw.io, look for the p1 plugin
. code example of how to integrate draw.io in your app
hint: if pulgins are not loaded, check the plugin folder link.
If you add the vertices on you own app, create your own style, and reuse it when creating.
updateStyles()
{
var style = new Object();
style[(<any>window).mxConstants.STYLE_SHAPE] =
(<any>window).mxConstants.SHAPE_IMAGE;
style[(<any>window).mxConstants.STYLE_PERIMETER] =
(<any>window).mxPerimeter.RectanglePerimeter;
style[(<any>window).mxConstants.STYLE_IMAGE] =
'../assets/transformer.png';
style[(<any>window).mxConstants.STYLE_FONTCOLOR] = '#000000';
style[(<any>window).mxConstants.STYLE_WHITE_SPACE] = 'wrap';
style[(<any>window).mxConstants.STYLE_VERTICAL_ALIGN] = 'bottom';
this.graph.getStylesheet().putCellStyle('transformer', style);
}
reuse this style whenever creating a vertex using insertVertex function.
try {
const parent = this.graph.getDefaultParent();
this.graph.getModel().beginUpdate();
const vertex = this.graph.insertVertex(parent, uuid.v4(), node, 40, 40, 80, 40, 'transformer');
} finally {
this.graph.getModel().endUpdate();
}

Forge viewer: Auto-start animation

We would like to trigger/auto-start an animation/simulation of a specific object (Revit ElementID) when the model loads in the Forge viewer. The goal would be to move a cube (Revit ElementID) back and forth on the floor in a repeating loop. Would this be possible using any relevant extension or code?
Yes it is possible but there is no built-in extension you can use out of the box. The animation logic has to be a custom implementation.
From a given ElementId/UniqueId you need to find the corresponding dbId, see that reply for a starting point on how to do that.
From a given dbId, you can obtain fragmentIds and use those to apply transforms to the components in the viewer. The animation logic has to be by your own application. You can refer to that article How to create animations in the viewer? or one of the several demos I wrote performing animations:
Kinematics - source
Physics - source
You can use the Autodesk.Viewing.GEOMETRY_LOADED_EVENT and Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT to trigger the animation logic, so you can make sure the model is fully loaded. See also that article: Asynchronous viewer events notification.
Hope that helps.

How to set opacity of each nodes

Is there anyway to set opacity of some nodes of the model?
For instance, create a override material and use it in renderer for some nodes rather than whole scene.
When loading a model, the viewer builds its internal spatial indexing structures (BVHs), and one of the factors it takes into account is the transparency of the different fragments. This is in order to ensure that semi-transparent objects are rendered after the opaque ones.
However, when changing the material of a fragment on-the-fly (after initial load of your model), the order is not updated because the viewer doesn't have a way to rebuild the BVHs on demand, and you can end up with something like opaque objects hidden by transparent ones ... We have a pending change request in order to add an API that would allow developers to rebuild BVHs, unfortunately it has not yet been added yet.
You may take a look at the following resources for example of modifying materials in the viewer:
Autodesk.ADN.Viewing.Extension.Material
Forge Viewer Custom Shaders - Part 1
Forge Viewer Custom Shaders - Part 2
Custom transparent meshes with View & Data API
Hope that helps
Yes, sure.
The ForgeFader app creates and sets override materials on certain nodes in the viewer:
Check it out in:
src/client/viewer.components/Viewing.Extension.Fader/Viewing.Extension.Fader.Core.js.

Flex 4.5 , How to create generic skinning library and dynamically change the theme of my AIR application?

I'm working on enterprise level AIR application, i need to change my application UI for multiple clients,it has a complex UI with more that 250 MXML skin files for all display objects such as buttons, combo box, containers, etc., Is it possible to create a generic skin library for managing skins and assets through CSS or i have to create a separate library for each of the clients?
Currently i'm duplicating the skin files for each client and changing the color values (styles) in CSS (which is the default.css for skin library) and Path data in skins.
Is there any easy way to create a skinning themes in flex 4.5 and managing assets(icons, fxg) in library?
Thanks in advance
Create a custom theme
I suppose you already know this, but creating a custom theme is simply a matter of:
creating a custom skin for every component
creating defaults.css file to assign those skins and perhaps provide some additional styling information
making sure that css file is included in the swc
applying the theme with the --theme compiler flag (or through whatever means your IDE provides)
Applying different colour schemes
You can use chromeColor and some other predefined styles to address this issue, but this approach may prove limiting. I solved this by substituting the Spark skin base classes with my own more elaborate versions. There's too much code to paste here, but it comes down to this:
I created an interface like this:
public interface IColorizedSkin {
function colorizeBorder(color:uint, lowLight:uint, highLight:uint):void;
function colorizeBackground(color:uint, lowLight:uint, highLight:uint):void;
function colorizeShadow(color:uint):void;
}
and I implemented this interface in my custom versions of:
SparkSkin
SparkButtonSkin
ColorizedItemRenderer
These three functions are called from an overridden updateDisplayList and use custom CSS style names like chromeBorderColor (which is an array of colours that expresses the base colour, the lowligth colour and the highlight colour of the border of a component).
All skins that need colorizing extend these base classes.
The defaults.css in the theme library comes with a default colour scheme, but you can override it by adding another css file with different colorizing directives to the client application.
Note that since these custom style names were not added as metadata to the components, you will only be able to assign these colours through CSS or through ActionScript, not through MXML attributes.
Colorizing icons
If you have an icon set that uses sufficiently neutral colours (for instance all icons are dark grey, or perhaps a grey gradient), you can colorize these too.
The simplest approach which works for solid colors is something like this:
if (iconDisplay) {
var colorTrans:ColorTransform = new ColorTransform();
colorTrans.color = getStyle("color");
iconDisplay.transform.colorTransform = colorTrans;
}
If you need something more finegrained, you'll have to work with a transform matrix.
Using different icons
I wouldn't bake icons into the skins, because that would reduce flexibility. I tend to include icons in the library swc, so one can access them from there.
If you need different icon sets for different client applications, simply create a swc including only these assets (i.e. no compiled code) for each set. As long as the names and paths inside those swc's are the same, you should be able to substitute one for the other.

Code for A Graphical User Interface window

How would someone go about coding a 'window'? I'm starting to make a GUI, and I want to learn how to code one. One that can be skinnable, and one that actually loops and creates itself at runtime. I understand that this might be a bit vague, so I'll add details.
One that actually 'creates' itself. Most GUI tutorials I've looked on depends on an 'image' that just gets added on the screen. I want to be able to use skins in my windows. One where my 'skin' is just a collection of 'borders'. Then when I insert window.create(50,50) where 50,50 is my height, width, It would just create that window, following the skin.
I understand that it probably follows just like when a language draws a rectangle, it just follows a different set of rules (maybe?). However, for all my Google-fu skills I cannot find a tutorial that teaches me this.
Please Help. I didn't include the language I used as you can see, because I believe I just need to know how to create one. Anyway though, I am using Actionscript 3. A tutorial would be just fine, or even A SINGLE CLASS THAT HAS THIS FUNCTIONALITY, I'll just study the code. Or if you know one, maybe a whole book about GUI and programming it :D
Pure As3.0 GUI coding is quite troublesome. I try to Googling, but not come out well. anyway for my case, i generate using a SWC, and Class Mapping and Customizing. but i'm not sure best way. in other way i use a bit101 library. this is gives me want Window, Charts, Componets easily of high abstraction. see the below image.
It can be pretty hard and complicated to do, or very easy, it just depends on how flexible your solution should be. You need firstly to design a structure of your program and approach to the problem.
I like to go from the image of how it should look like from API point of view. I think I would create a GUI element like this:
var wholeGui:MyGUI = new MyGUI();
var window:IGuiElement = new GuiWindow(dataObject, skinObject);
wholeGui.addElement(window);
So what would you need?
1) Object that would manage all GUI elements. Why? Simply because your GUI elements shouldn't be destroyed by themselves if user will click "X" on your little window. The wholeGui object would manage them and listen for any events including those that would destroy them. You may consider creating custom events for interaction between the wholeGui object and your window object if this interaction is going to be complicated.
2) Interface for your GUI objects. Some problem here is that AS3 actually doesn't have interface for Sprite, and you would like to interact with it like with extended Sprite. The workaround here is to have in this interface a declaration like this:
function asSprite():Sprite;
And your implementation in GuiWindow would look like this:
public function asSprite():Sprite {
return this;
}
And your GuiWindow class should extend Sprite of course. Then you would have access to it's Sprite properties and methods by writing for example: window.asSprite.startDrag();
This interface should give you abilities that you need to operate on your GUI element.
3) Class for your GUI element, in this example GuiWindow.
4) Class for your data that would be injected into your element. If you would load data dynamically, and from some location, you would need to deal with the situation when no data can be provided - but that logic would be inside your window.
5) Class for your skin - so you would be able to dynamically create a skin object and use it to create your window in a way you want.
That's just few thoughts to consider.
PS. It may be good idea to fill GuiWindow object with data AFTER creating it, and not in constructor, as you would be able to visualize loading process then.