tracking position/location in test keyboard & mouse mode (not ppt) with new vizconnect - vizard

I can track location fine pre - vizconnect using code like this:-
vrpn7 = viz.add('vrpn7.dle')
posTracker = vrpn7.addTracker('PPT0#WorldViz-PC', 0 )
and then
x,y,z = posTracker.getPosition()
but I now use the new vizconnect e.g.
vizconnect.go( 'vizconnect_hmd_ppt.py' )
I'm wondering what the recommended way is to then access the trackers from my main project '.py' file and particularly when I'm using a keyboard/mouse scenario to simulate movement for during program development.
Any advice would be most welcome.
Thanks

Actually it was pretty straightforward:
first check the names of the trackers using:
print( vizconnect.getTrackerDict() )
it may return something like this
'mouse_and_keyboard_walking'
along with some others e.g. inertia cube, then do
gTracker = vizconnect.getTracker( 'mouse_and_keyboard_walking' )
or
gTracker = vizconnect.getTracker( 'PPT0#WorldViz-PC' )
then periodically call (probably on a callback() ):-
x, y, z = gTracker.getPosition()

Related

Ironpython script in Ansys Customization tool

I'm a beginner in Python and I'm working with the Ansys Customization Tool (ACT) to add my own extension.
Is there a direct way to fill a file with every node's coordinates after deformation?
hopefully in 3 lines or columns: x , y , z
So far I only found the GetNodeValue object but it only gives me the displacement and I need the deformed coordinates for the entire model.
My first idea was to add the displacements to the initial coordinates but I didn't manage to do it.
Many thanks for your help
Lara
APDL Snippet
Add an APDL Snippet in the solution part of the tree:
/prep7
UPGEOM,1,1,1,file,rst ! adds the displacements to the nodal coordinates.
cdwrite,geom,nodesAndelements,geom ! Writes node and element data to nodesAndelement.geom
I'm not sure if you can work with the output format from cdwrite, but this is the quickest solution i can think of.
If you want to automate you have to insert the command snippet via
solution = ExtAPI.DataModel.Project.Model.Analyses[0].Solution
fullPath = "path//to//snippet"
snippet = solution.AddCommandSnippet()
snippet.ImportTextFile(fullPath)
ACT
If you want to stay in ACT it could be done like this:
global nodeResults
import units
analysis = ExtAPI.DataModel.Project.Model.Analyses[0]
mesh = analysis.MeshData
# Get nodes
allNodes = mesh.Nodes
# get the result data
reader = analysis.GetResultsData()
# get the deformation result
myDeformation = reader.GetResult("U")
nodeResultsTemp = []
result_unit = myDeformation.GetComponentInfo("X").Unit
for node in allNodes:
# get node deformation and convert values in meter
deformationNode1 = myDeformation.GetNodeValues(node.Id)
deformationNode1[0] = units.ConvertUnit(deformationNode1[0],result_unit,"m","Length")
deformationNode1[1] = units.ConvertUnit(deformationNode1[1],result_unit,"m","Length")
deformationNode1[2] = units.ConvertUnit(deformationNode1[2],result_unit,"m","Length")
# add node coordinates (in meter) to the displacement
mesh_unit = mesh.Unit
node1 = mesh.NodeById(node.Id)
node1CoorX = units.ConvertUnit(node1.X,mesh_unit,"m","Length")
node1CoorY = units.ConvertUnit(node1.Y,mesh_unit,"m","Length")
node1CoorZ = units.ConvertUnit(node1.Z,mesh_unit,"m","Length")
deformationNode1[0] = deformationNode1[0]+node1CoorX
deformationNode1[1] = deformationNode1[1]+node1CoorY
deformationNode1[2] = deformationNode1[2]+node1CoorZ
nodeResultsTemp.append([node1.X,node1.Y,node1.Z,deformationNode1[0],deformationNode1[1],deformationNode1[2]])
nodeResults = nodeResultsTemp

How to measure distance in crs.simple?

I have a non-geographic map aka flat image using CRS.Simple extended by a custom transformation. Everything works fine so far, but now I want to add a distance measurement button. I'm confident I could implement a distance measurement between two markers myself, but the dynamic line drawing and measuring is still a bit above my skills, so I hoped I could use a plugin. None of the ones I found, did offer this though. After looking at the plugins page of leaflet, I tried this fork https://github.com/aprilandjan/leaflet.measure of leaflet.measure originally by https://github.com/jtreml/leaflet.measure as it seemed to offer the ability to add custom units - in my case pixels.
I added this:
L.control.measure({
// distance formatter, output mile instead of km
formatDistance: function (val) {
return Math.round(1000 * val / scaleFactor) / 1000 + 'mapUnits';
}
}).addTo(map)
Unfortunately, the result is a number far too big compared to the pixelsize of the map (4096x4096). distance() returns the expected 1414.213562373095 between a point 1000,1000 and one at 2000,2000. Calculating distanctTo returns 8009572.105082839 instead though. I use this at the beginning of my file
var yx = L.latLng;
var xy = function(x, y) {
if (L.Util.isArray(x)) { // When doing xy([x, y]);
return yx(x[1], x[0]);
}
return yx(y, x); // When doing xy(x, y);
};
If I log val to the console, I get things like this:
20411385.176805027
7118674.47741132
20409736.502863288
7117025.8034695815
20409186.004645467
20409736.502863288
That's likely some problem of the function trying to calculate latlng without a proper reference system.
Anyone got an idea how to solve this? I feel like it can't be overly difficult, but I don't know exactly where to start.
I found a way to do it, even though it feels a bit 'hacky':
I replaced the line
var distance = e.latlng.distanceTo(this._lastPoint)
in the _mouseMove and the _mouseClick events of leaflet.measure with
var currentPoint = e.latlng;
var lastPoint = this._lastPoint;
var distance = map.distance(currentPoint, lastPoint);
as the distance() method of the map returns meters, or in the case of a flat image, pixel values. And those we can translate in whatever unit we want in our flat image.
If anyone has a more elegant way, I'm all ears!

Assimp: Load .blend file with correct rotation

I have a simple .blend level which looks like it's flipped when importing with Assimp:
Blender uses Z as its Up vector, my engine uses Y. There are no export/save options in Blender that allows me to set that in .blend
Afaik Assimp should handle this for me. Here's how I'm loading the model, converting it to a runtime format for my engine:
// vertices, normals and uvs
{
u32 VertexCount = SrcMesh->mNumVertices;
u32 ByteCount = VertexCount * sizeof(f32) * 3;
DstMesh->VerticesCount = VertexCount;
DstMesh->Vertices = new vec[VertexCount];
memcpy(DstMesh->Vertices, SrcMesh->mVertices, ByteCount);
FAIL_IF_NOT(SrcMesh->mNormals, "Model doesn't have normals");
DstMesh->Normals = new vec[VertexCount];
memcpy(DstMesh->Normals, SrcMesh->mNormals, ByteCount);
FAIL_IF_NOT(SrcMesh->mTextureCoords[0], "Model doesn't have UVs");
DstMesh->UVs = new vec[VertexCount];
memcpy(DstMesh->UVs, SrcMesh->mTextureCoords[0], ByteCount);
}
// faces
{
DstMesh->FacesCount = SrcMesh->mNumFaces;
DstMesh->Faces = new mesh_face[DstMesh->FacesCount];
For(i32, F, DstMesh->FacesCount)
{
aiFace *SrcFace = &SrcMesh->mFaces[F];
mesh_face *DstFace = &DstMesh->Faces[F];
FAIL_IF_NOT(SrcFace->mNumIndices == 3, "Model is not triangulated. Face index %d has %d indices", F, SrcFace->mNumIndices);
memcpy(DstFace->Indices, SrcFace->mIndices, 3 * sizeof(u32));
}
}
Note I also tried finding the node that mesh's belong to, and transforming the vertices/normals by that node's final transform (by final I mean I recurse all the node's parents and apply their transforms and finally the node's local transform) -- But that didn't do anything because the mesh has no parent.
My questions are:
What is the right way to load .blend files?
Shouldn't Assimp be handling this on its own on import?
or do I need to manually rotate/flip things?
Here's the referenced model: https://www.dropbox.com/s/hwsyfyqip5pqhrh/StusRoom.blend?dl=0
Thanks for any help!
I figured out that Blender expect .glb files to be in XZ-Y axis order, so perhaps this is true for .blend files as well.
Regarding the AssImp - I was dealing with this issue myself on my work, and I figured out that the problem is the AssImp - check the link: https://github.com/assimp/assimp/issues/849 (as you can see this is still open, even though it's over 5 years old now)
I believe you need to figure out some workaround to somehow manually rotate the file, since assimp will rotate it for you.
Hope it helps! Best regards

OrientDB create edge between two nodes with the same day of year

I'm interested in creating an edge (u,v) between two nodes of the same class in a graph if they share the same day of year and v.year = u.year+1.
Say I have vertices.csv:
id,date
A,2014-01-02
B,2015-01-02
C,2016-01-02
D,2013-06-01
E,2014-06-01
F,2016-06-01
The edge structure I'd like to see would be this:
A --> B --> C
D --> E
F
Let's set the vertex class to be "myVertex" and edge class to be "myEdge"? Is it possible to generate these edges using the SQL interface?
Based on this question, I started trying something like this:
BEGIN
LET source = SELECT FROM myVertex
LET target = SELECT from myVertex
LET edge = CREATE EDGE myEdge
FROM $source
TO (SELECT FROM $target WHERE $source.date.format('MM-dd') = $target.date.format('MM-dd')
AND $source.date.format('yyyy').asInteger() = $target.date.format('yyyy').asInteger()-1)
COMMIT
Unfortunately, this isn't correct. So I got less ambitious and wanted to see if I can create edges just based on matching day-of-year:
BEGIN
LET source = SELECT FROM myVertex
LET target = SELECT from myVertex
LET edge = CREATE EDGE myEdge FROM $source TO (SELECT FROM $target WHERE $source.date.format('MM-dd') = $target.date.format('MM-dd'))
COMMIT
Which still has errors... I'm sure it's something pretty simple to an experienced OrientDB user.
I thought about putting together a JavaScript function like Michela suggested on this question, but I'd prefer to stick to using the SQL commands as much as possible for now.
Help is greatly appreciated.
Other Stack Overflow References
How to print or log on function javascript OrientDB
I tried with OSQL batch but I think that you can't get what you want.
With whis OSQL batch
begin
let a = select #rid, $a1 as toAdd from test let $a1 = (select from test where date.format("MM") == $parent.$current.date.format("MM") and date.format("dd") == $parent.$current.date.format("dd") and #rid<>$parent.$current.#rid and date.format("yyyy") == sum($parent.$current.date.format("yyyy").asInteger(),1))
commit
return $a
I got this
but the problem is that when you create the edge you can not cycle on the table obtained in the previous step.
I think the best solution is to use an JS server-side function.
Hope it helps.

Is there a way to change directory in Modelica/Dymola automatically?

I have the following problem:
I have over 20 different models which I want to simulate one after another but I want to change the simulation directory each time.
Right now I'm manually changing directory after each simulation (from ./ModelOne to ./ModelTwo) and I'd like to know if there's a way to change it automatically when I initialize or translate the new model.
Regards
Nev
the best way is to write a script I think:
pathOfSave = {"E:\\work\\modelica\\SimulationResult\\Model1\\","E:\\work\\modelica\\SimulationResult\\Model2\\"};
nbSim = 2;
pathOfMod = { "MyModel.",
"MyModel.};
modelsToSimulate = { ""Model1" ,
"Model2"};
//If equdistant=true: ensure that the same number of data points is written in all result files
//store variables at events is disabled.
experimentSetupOutput(equdistant=false, events=false);
//Keep in the plot memory the last nbSim results
experimentSetupOutput(equdistant=false, events=false);
for i in 1:nbSim loop
//delete the result file if it already exists
Modelica.Utilities.Files.removeFile(pathOfSave + modelsToSimulate[i]);
//translate models
translateModel(pathOfMod[i]+modelsToSimulate[i]);
// simulate
simulateModel(
pathOfMod[i]+modelsToSimulate[i],
method="dassl",
stopTime=186350,
numberOfIntervals=nbOfPoi,
resultFile=pathOfSave + modelsToSimulate[i]);
end for;
You can also put the command cd("mynewpath") in the initial algorithm section, if you want it tobe attached to the model.
model example
Real variable;
protected
parameter String currDir = Modelica.Utilities.System.getWorkDirectory();
initial algorithm
cd("C:\\Users\\xxx\\Documents\\Dymola\\MyModelFolder");
equation
variable = time;
when terminal() then
cd(currDir);
end when;
end example;
In any case you can find all commands of dymola in the manual one under the section "builtin commands".
I hope this helps,
Marco