Model aggregating in viewer - coordinate issue - javascript

I am dynamically aggregating models in the Viewer (coming from multiple BIM files). Basically, I initialize the viewer, and then LoadDocument and LoadModel for each model that user chooses to view, dynamically.
These are mostly NVC files (what I used for testing), which are sharing the coordinate system. Models getting dynamically loaded and getting 'stitched' correctly.
However, coordinate system is getting screwed up when the second model gets loaded - not always but in some cases (in v6.3 - haven't checked previous versions). When this happens, I can notice the followings:
When I click 'home' icon in the viewer, it doesn't show the full aggregated model but only shows the first loaded model in the center and rest go outside screen.
When I click an element to select, it selects something else (with an offset), and some cases selects nothing (meaning, clicked coordinates has been interpreted incorrectly).
I have tried multiple combinations and this problem seems to happen when first loaded model is not occupying full size of the aggregated model (say, one floor of the building).
I figured out a solution though. After loading the models (every time when user choose some), if I 'hide' all models and 'show' them again, it fixes the problems with click and AGGREGATED_SELECTION event.
This is not a nice user experience because I want to be able to load the models in the background while user is moving around the previously aggregated model-set. If I hide/show after loading the new one, it will be annoying to user.
Is there a way to 'reset' the coordinate system of the viewer (to the same effect what happens when hide/show the models)?
I would appreciate some help to get around this issue.
Thanks
Bandu

ok, so there is a massive offset, causing a precision issue. Which is why you are seeing lots of 'jittering' of the camera.
To fix this... we need to correct the massive offset, by returning all the geometry closer to origin manually. (or fixing the original navisworks file).
First, let's roughly figure out the offset value...
Hold down ALT-key and click anywhere on an object. This sets a green dot, the pivot point. Then use viewer.navigation.getPivotPoint() to get the x,y,z value. (details: https://github.com/wallabyway/markupExt/issues/2).
You should see an xyz value like this...
Z.Vector3 {x: 1296285.515098644, y: 14995636.431742325, z: 364.26238179027337}
Now, adjust set the global offset using this value, to correctly move all the models closer to 0,0,0. like this...
line 70:
var modelOptions = {
sharedPropertyDbPath: doc.getPropertyDbPath(),
globalOffset: {x:1296285.515098644, y: 14995636.431742325, z:0}
};
viewer.loadModel(svfUrl, modelOptions, onLoadModelSuccess);
`
This reverses the effect of this big offset. The result is the geometry stops flickering and the camera movement stops 'jittering' due to precision issues.
Let me know if that works for you.
Michael
ps. you can pull the 'exact' global-offset out of the small side-file AECModelData.json, see blog: forge.autodesk.com/blog/add-revit-levels-and-2d-minimap-your-3d

Related

How to make a button that allows a WebGL model to go back to its initial orientation?

I am building a plugin for Grafana. In this plugin, I load a model with a .fbx extension, using threejs, orbitcontrols and FBXLoader. The plugin gets data from Grafana and uses this to update the Roll, Pitch and Yaw of the model.
However, because I have added controls, it is possible to zoom in/zoom out or to look at the model from a different angle.
Now I want to create a button that gets the model back to its initial orientation when it is clicked on. I think I have to make a button that calls a function backToInitial() or something, and then this function has to change the position and rotation of the camera (so not from the model itself?) to its initial state. I have tried multiple things, but nothing has worked yet. I am having the most trouble with putting the button in the right place and adding an event listener that reacts when the button is clicked (because the html and js are in separate files).
Does anyone know if this idea is logical and how to do this?
Thanks a lot in advance!

Timing issue with image load?

I have a draggable image class that displays an image as expected when it is the only object on the stage. But when I add other graphics objects the image is not visible until I mouseover where the image is located.
It seems like the stage needs an extra update when there are more graphics objects on the display list. Calling tick() or setting my update flag manually doesn’t solve the issue (presumably this happens too quickly).
I can hack around it by putting a counter in the tick function like
if(update || ticks < 10). Clearly, this is not really a solution; the tick code shouldn’t have to check the counter every tick, forever.
Does anybody know the correct way?
You can see it here: http://eduk8r.org/bridge/. You’ll have to mouseover the image the first time, though. (The image is located to the left hand side of the bridge).
The relevant code is in controller.js and DraggableImage.js.
UPDATE: I had thought that reloading the page was sufficient to display the image but that only seems to happen locally.

Why does the performance of this HTML5 app drop upon coordinate load

I wrote this Mandelbrot plotter in HTML5 and it has a reproducible performance bug that I can't figure out.
In the Plot Controls section, there's the ability to save coordinates into a pick list to be able to return directly there later. If I select a saved set of coordinates, however, and then click "Load", the performance suddenly becomes so slow that at first I thought it was hanging the script (it will eventually start to develop the image as it's supposed to).
I cannot figure out why. The onclick handler for the Load button (line #258) simply calls gotoCoord() (line #457). The gotoCoord function simply sets several of the plot parameters (xOff, yOff, fMag) and then calls initDisplay(). I do those exact things in several other places with no ill effects (mousedown on line 124, zoomOut on line 386, zoomIn on line 394). I can't figure out what's different about gotoCoord.
I've done repeated comparison testing, navigating to a plot and timing how long it takes to develop the image. Then I save the coords and load them. The performance hit is drastic.
Does anyone else see what I'm missing?
This question is answered, so just taking it out of the unanswered list.
#DCoder's comment solved it. The plot parameters are stored in localStorage and the pick list is loaded from there. Of course, when loading from localStorage, the values will all be strings. That's what was different about gotoCoord from the other functions. Since the parameters are used in the plot (lines 589 and 590), the text must be converted to a number for each calculation of each pixel in each frame!
Three little plus signs fixed it.

HTML Canvas Tracing

I'm trying to build something in HTML5/Canvas to allow tracing over an image and alert if deviating from a predefined path.
I've figured out how to load an external image into the canvas, and allow mousedown/mousemovement events over it to draw over the image, but what I'm having trouble getting my head around is comparing the two.
Images are all simple black on white outlines, so from what I can tell a getPixel style event can tell if there is black underneath where has been drawn upon or underneath where the mouse is on.
I could do it with just the mouse position, but that would require defining the paths of every image outline (and there are a fair number, hence ideally wanting to do it by analyzing the underlying image)..
I've been told that its possible with Flash, but would like to avoid that if possible so that compatability with non-flash platforms (namely the ipad) can be maintained as they are the primary target for the page to run.
Any insight or assistance would be appreciated!
I think you already touched upon the most straight-forward approach to solving this.
Given a black and white image on a canvas, you can attach a mousemove event handler to the element to track where the cursor is. If the user is holding left-mouse down, you want to determine whether or not they are currently tracing the pre-defined path. To make things less annoying for the user, I would approach this part of the problem by sampling a small window of pixels. Something around 9x9 pixels would probably be a good size. Note that you want your window size to be odd in both dimensions so that you have a symmetric sampling in both directions.
Using the location of the cursor, call getImageData() on the canvas. Your function call would look something like this: getImageData(center_x - Math.floor(window_size / 2), center_y - Math.floor(window_size / 2), window_size, window_size) so that you get a sample window of pixels with the center right over the cursor. From there, you could do a simple check to see if any non-white pixels are within the window, or you could be more strict and require a certain number of non-white pixels to declare the user on the path.
The key to making this work well, I think, is making sure the user doesn't receive negative feedback when they deviate the tiniest bit from the path (unless that's what you want). At that point you run the risk of making the user annoyed and frustrated.
Ultimately it comes down to one of two approaches. Either you load the actual vector path for the application to compare the user's cursor to (ie. do point-in-path checks), or you sample pixel data from the image. If you don't require the perfect accuracy of point-in-path checking, I think pixel sampling should work fine.
Edit: I just re-read your question and realized that, based on your reference to getPixel(), you might be using WebGL for this. The approach for WebGL would be the same, except you would of course be using different functions. I don't think you need to require WebGL, however, as a 2D context should give you enough flexibility (unless the app is more involved than it seems).

Capture website screenshot using javascript

I've seen similar questions asked and the answers were not quite what I'm after. Since this question is slightly different, I'm asking again - Hopefully you'll agree this isn't a duplicate.
What I want to do: Generate an image showing the contents of my own website as seen by the user (actually, each specific user).
Why I want to do it: I've got some code that identifies places on the page where the user's mouse hovers for a significant length of time (ppl tend to move the mouse to areas of interest). I also record click locations. These are recorded as X/Y co-ords. relative to the top-left of the page
NB: This is only done for users who are doing usability testing.
I'd ideally like to be able to capture a screenshot and then use something server-side to overlay the mouse data on the image (hotspots, mouse path, etc.)
The problem I have is that page content is very dynamic (not so much during display but during server-side generation) - depending on the type of user, assigned roles, etc... whole boxes can be missing - and the rest of the layout readjusts accordingly - consequently there's no single "right" screenshot for a page.
Option 1 (which feels a little nasty): would be to walk the DOM and serialize it and send that back to the server. I'd then open up the appropriate browser and de-serialize the DOM. This should work but sounds difficult to automate. I suspect there'd also be some issues around relative URLs, etc.
Option 2: Once the page has finished loading, capture an image of the client area (I'd ideally like to capture the whole length of the page but suspect this will be even harder). Most pages don't require scrolling so this shouldn't be a major issue - something to improve for version 2. I'd then upload this image to the server via AJAX.
NB: I don't want to see anything outside the contents of my own page (chrome, address bar, anything)
I'd prefer to be able to do this without installing anything on the end-user pc (hence javascript). If the only possibility is a client-side app, we can do that but it will mean more hassle when getting random users to usability test (currently, we just email friends/family/guinea pigs a different URL)
One alternative solution would be to "record" the positions and dimensions of the main structural elements on the page:
(using jQuery)
var pageStructure = {};
$("#header, #navigation, #sidebar, #article, #ad, #footer").each(function() {
var elem = $(this);
var offset = elem.offset();
var width = elem.outerWidth();
var height = elem.outerHeight();
pageStructure[this.id] = [offset.left, offset.top, width, height];
});
Then you send the serialized pageStructure along with the mouse-data, and based on that data you can reconstruct the layout of the given page.
One thing we always talk about where I work is the value of ownership vs the cost required to make something from scratch. With the group I have, we could build just about anything...however, at a per-hour rate in the $100 range, it would need to be a pretty marketable tool or replace a very expensive product for it to be worth our time. So, when it comes to things like this that are already done, I'd consider looking elsewhere first. Think of what you could do with all that extra time....
A simple, quick google search found this: http://www.trymyui.com/ It's likely not perfect, but it points to the fact that solutions like this are out there and already working/tested. Or, you could download a script such as this heatmap Obviously, you'd need to add a bit to allow you to re-create what was on the screen while the map was created.
Good Luck.
IMO, it's not worth reinventing the wheel. Just buy an existing solution like ClickTale.
http://www.clicktale.com/

Categories

Resources