hello im experimenting with web-ifc-viewer, and im currently to to get the geometry of a certain object by its express id or by pointing and clicking on it.
i have searched thoroughly in ifcviwer.context.item couldn't find anything.-
also if have to use web-ifc-viewer, how do i implement it with web-ifc-viewer in a react application.
I have went through every web-ifc-viewer method but could not find any that would give me the geometry of the target by its id or clicking on it, although there are many methods to use after you can get your hands on the objects mesh or geometry, that's what I need it for.
Related
I've explored the docs, the code, and all of the questions/discussions I can find on this library but haven't found any discussion of whether this is possible.
Basically we want to only show the marker if the list contains some particular element-type as its direct child in the source HTML.
I'm aware of Custom Rendering but even with all of the information I've reviewed, I don't see any way to accomplish this.
Can this be done?
This is a question about javascript and three.js coding style conventions. I prefer to use the latest ES-whatever conventions.
I'm wondering if instead of doing the usual:
var scene = new THREE.Scene();
var cube = new THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.MeshBasicMaterial(0xffffff))
scene.add(cube)
it would be ok to store the mesh object (and other objects, maybe lights and even camera) as properties of the scene object:
const scene = new THREE.Scene(); // or var, but that's not my question
scene.cube = THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.MeshBasicMaterial(0xffffff))
scene.add(scene.cube)
I like the idea of having references to all the three.js objects underneath the scene namespace -- makes it easier for me to access them later. I know I could use this with .name and .getObjectByName but that takes more code and seems messier to me.
There is a field on Object3D derived objects called .userData that you can store stuff that should get saved/serialized. But as far as storing props directly on objects.. It works.. but kinda has potential for problems if you end up overwriting something or later revs of three make use of your property name...
Edit: after reading the other posts here, they raise some good point, and I also wanted to throw out there that you can subclass the built-in three objects and make your own custom type that has your stuff. That might be tidier.
As far as separation of concern goes, you don't want to use Three's objects as data holders. It might seem like an easy way out, but will greatly reduce maintainability of your code. There is nothing preventing you from doing it today, though. Just consider, that you will have
scene.cube
scene.children[0] //same cube
scene.getObjectById(... cube id ...) //same cube
//... byName, ...byProperty etc. all pointing to the same cube
Remember, Scene extends Object3D with all its methods and properties, so, in the example scene below all objects are Object3D with each having children[] property.
[scene]
+----^-----------------------------+
[chairGroup] [light]
+--^--+-----+-----+-----+------+
[leg] [leg] [leg] [leg] [back] [seat]
Doesn't each node above look similar to DOM's Element?
I would encourage you to think about your scene as a tree. In fact, any UI is an n-tree of elements: web, mobile, X11 etc., and every UI framework is a tool to manipulate such tree. All approaches you use to manipulate DOM tree effectively work here.
Hence, below are various ways you can organize your code, from simple to more complex:
hello world rotating cube example is fine, 15-20 lines of code are ok as-is
rendering context: move scene, camera and renderer into some context object you can pass around your layers. Think of it as an equivalent of document in the browser.
high-level "Shadow DOM": organize a tree of your own components that each handle a group of 3d objects, make them react to events - external from UI clicks etc., or from Three, like visitor pattern during rendering. You can either keep references to 3d objects on these components, or recursively pass your structure to a function to adjust scene's hierarchy. Examples of such components in your tree could be Chair, Building, Planet, Starship etc.
data model: it might be tempting to store some data inside your components, but you should have a distinction between external data, usually a bit global, like numeberOfPlanets, timeOfDay etc., and internal data, like current rotation speed of a planet. Latter can be kept as part of your scene domain components.
full MVC: as with any UI, model-view-controller is applicable here. E.g. you can follow this intro into three.js MVC.
mediators, observers and usual workflows. See, e.g. my answer here.
... all the way to Redux-like immutable state management system
I hope, this answer will help people do some tactical architecture around Three.js that suits their project best.
Afternoon. I have an FLA with a single MovieClip on the stage - the clip is named myThing in the Library and also has an instance name of myThing. On another layer I have the following script:
this.myThing=this.getChildByName("myThing");
console.log(this.myThing);
When I run this in a WebGL project it works as I'd expect and returns a JS object but when I run the same thing in a canvas project (which is what I need to use) it comes back null.
Initially, can anyone explain what the difference is between a WebGL and a canvas project in Adobe Animate CC and how I can get a reference to child clips to control their timelines?
Along with that, can anyone point me to any decent resources on scripting these projects? It seems like no matter what I search for I always end up back at that *!#%£¡ rabbit tutorial that manages to cram very little info into an awful lot of words.
Thanks all, your help is always appreciated :)
So I was being a numpty.
The name property of any asset defaults to null. This is not a problem because the getChildByName() method is not really necessary (for me at least) once I realise that you can just call this.someChild.someMethod().
I got hooked up on the wrong approach because it was the only one I could find examples of. I'm still finding documentation very sketchy and not very helpful when compared to AS3 or even competing JS libraries like Greensock
Also not sure why my first approach worked in WebGL but not canvas. Ah well, onwards and upwards...
WebGL and HTML5 Canvas documents work somewhat differently in Animate CC.
In WebGL, symbols having instance names are accessible as follows:
var mySymbol = this.getChildByName("instance-name");
In Canvas, the same can be done as follows:
var mySymbol = this.instance-name;
Unnamed instances can be referenced using this.getChildAt(index) in both canvas and WebGL.
Once a reference to the required instance is obtained, you can easily control it as desired. (gotoAndPlay()/Stop() etc.)
PS: In canvas, Symbol-instance names are not explicitly set as name properties of corresponding symbols in the output - hence the name property is returned as null.
Firstly, I'm a big fan of the site and have used it countless time to help me when stuck on a problem, but this is the first time I have come across something that has required me to write a question because I simply cannot find a situation like this.
I have a Json file which I am loading a bunch of data from that I then run through with my code to put the right data in the right places so it can be rendered by ThreeJS (quick side note, big thanks to mrdoob, westLangley and the rest of the ThreeJS team for what they've done and their continued engagement with helping people here).
So at that point the mesh is able to be rendered and have orbit controls and so on. Then I made just a simple exporter in a similar style to that of ThreeJS.org/editor. The big difference being that I simple use JSON.stringify on a number of objects (the one I will focus on here is called "geo") and write their data to a new Json (json2). The goal being that now I can simply load json2 into the new program which will populate "geo" with the data of the json2's geo thus circumventing all of the processing that goes into putting the data in the right places.
Now here is the issue. All the data seems to be the same between the two "geo"s, but when going to color a face in the code by using:
for ( var i = 0; i < sD.geo.faces.length; i ++ ) {
var face = sD.geo.faces[ i ];
face.color.setStyle("#0066FF");
}
the error that "face.color does not have a function called setStyle" (rough quote from memory) appears. And again, this works perfectly fine in the first program.
So I looked into it further and it seems that when digging into the "face" variable in the code above via firebug, it doesn't have a constructor or prototype in its drop down menu, as it does have the first program. I'll upload screenshots of the two dropdowns to show more visually in a little while. )Update: Nevermind, I don't have enough rep to post them. Forgot about that haha)
So the data I have doesn't have the constructor/methods, so could it be that the data I'm setting the sD.geo equal to? (even did it so that it just sets the vertices from the json2 to the sD.geo.vertices so as to avoid that but didn't work, obviously). Any other ideas as to what my issue could be? Should I add the methods to the json2 and how because I looked into that a lot and couldn't find any good examples on it.
I apologize if I jumped all over the place throughout this, I tried to keep it as linear as possible as to cause as little confusion as possible.
Any and all help is appreciated, and I am more than willing to answer any questions anyone has that I am able to.
Thanks!
After tinkering with this more, I found a solution for adding the json2's geometry data to the new program's geo.
function loadGeo(json) {
var loader = new THREE.ObjectLoader();
var object = loader.parse( json );
var pushed = false;
object.traverse(function(child) {
if (child.geometry !== undefined && pushed !== true) {
addGeometry(child.geometry);
$.each(child.material.materials, function(cm, cMat) {
sD.geo.materials.push(cMat);
});
pushed = true;
}
});
}
Now this works, but it is far from flawless. For example, in object.traverse I put in a check to only add the first geometry and material it finds and ignore the rest. Both because I am only adding a single geometry and I haven't used/looked into traverse enough to know of any proper exit. Also in the json, the materials (there are ~24 for the single geometry) are very deep in the object tree, which is okay but probably not optimal.
The one big issue that I have come across with this is that for some reason, the materialIndexes I assigned to the faces in the geometry aren't assigned properly; they all are just set to 0(from the ones I looked at, there are ~11,000 faces so couldn't look through them all). An odd issue, and will edit my answer if and when I find solutions to this or others give solutions on here.
I figured this out by going back to the three.org/editor and seeing how their importer worked and making a rough attempt at something that uses the threejs loaders in the same way, but really make it less tied into the actual Editor and make it very "bare-bones" so that it serves my purposes alone. That being said, I'm curious if there is any ThreeJS importer which uses the loaders that can just populate variables in the way like I am doing here.
I've been doing driving directions in my map app using the directionsRenderer, so it renders both the path (on the map) and the html list of directions. My app works basically like this example: http://code.google.com/apis/maps/documentation/javascript/examples/directions-draggable.html
However, now I've been asked to make it a little more like the directions on Google Maps proper, for instance here
My client would like the little popups when you hover over the html items, as well as the little icons showing right turn, bear left, merge, etc.
I've managed to render my own html from the DirectionsService response, and hook up events for hovering and associate them with points on the map, but where I could use help is:
Getting the turn by turn icons. I imagine this isn't easy because I get each step as html text ("Take exit 433 on the left to merge onto I-80 E toward Bay Bridge/Oakland"), and I imagine that could be challenging to parse reasonably to determine which icon to show
Making the little mini-popups over the map. Although I can make the popups themselves, it's probably challenging or impossible to do it the exact same way because I don't have a short version of the instructions.
In any case, I thought I'd check if anyone knows a way to do this sort of thing -- not necessarily exactly, but just closer to it -- or if I'm just out of luck because google hasn't made any of that sort of functionality available via their api.
You are correct that you will have to examine strings to get turn icons. You can parse the DirectionsResult object yourself (it is "JSON-like" according to Google's documentation) rather than using the DirectionsRenderer if you wish, but I don't think it will get you anything much. Here's how it would go:
The DirectionsResult.route property will be an array of DirectionsRoute objects. If you didn't set provideRouteAlternatives to true, then there will only be one DirectionsRoute object in the array.
The DirectionsRoute object, in turn, has a property called legs. That property is an array of DirectionsLeg objects. If you have specified no waypoints (i.e., an intermediary destination), just a start and end point, then this array will also only have one object in it.
The DirectionsLeg object, in turn, has a property called steps. It will be an array where each element will be a DirectionsStep object.
The DirectionsStep object has a property called instructions. That is a string and is what you will have to examine using a regexp or whatever to figure out what turn icon to use. (It's possible that this may be easier to work with than the HTML you mention that I imagine is coming from the DirectionsRenderer. Or it may be possible that it isn't any easier whatsoever. I'm not sure. I've never actually done it.)