How to reverse a transformation by matrix in Blender? - python

I have a selected mesh (creatively called 'selected') which I want to work with in its local space so I use the following:
tmesh = NMesh.GetRawFromObject(selected.name)
tmesh.transform(selected.matrix)
I then do a bunch of calculations on its verticies and remove them by index, which works great.
What doesn't work so great is when I try to add them back later from a list of vert.co objects. They end up being positioned correctly relative to each other, but nowhere near the original verticies.
for v in tmesh.verts:
toAdd.append(v.co)
mesh = selected.getData(mesh=1)
mesh.verts.extend(toAdd)
I realized this is because the object is in a different space. So I think what I need to do is translate the new verticies back to the old space... but my understanding of what exactly is going on here is fuzzy at best. How do I "undo" the tmesh.transform(selected.matrix) command?
A more thoroug explanation of what I'm doing can be found here: http://www.kellbot.com/2010/11/lego-plans-now-with-better-rendering/

I'm not familiar with Blender specfically, but after a quick peek at the documentation, in principle it seems like you ought to be able to use the invert() Matrix method to obtain the inverse transformation of the selected.matrix (perhaps after first making a copy() of it).

Related

Read a vtr file transform it and write it again creates no file

I am completely new to dealing with vtk(/vtr/vtu/..) outside of paraview but I want to make my workflow a bit easier so I want to do some data transformation outside of paraview.
Basically I have two simulations but the origin and the axis are different. The origin difference changes every time step so I want to transform my files such that they are aligned before opening them in paraview such that I not constantly have to change the values in the transform filter when I want to look at a different time step. I was first trying to achieve this by just rotating and transforming one file.
My approach is as such (based on a lot of other webpages so unfortunately I cannot track down anymore what came form where):
import vtk
reader = vtk.vtkXMLRectilinearGridReader()
reader.SetFileName(file_name)
reader.Update()
data = reader.GetOutput()
transform = vtk.vtkTransform()
transform.RotateZ(90)
transform.Translate(2.34375, 4.6875, 2.34375)
transformFilter=vtk.vtkTransformFilter()
transformFilter.SetTransform(transform)
transformFilter.SetInputData(data)
transformFilter.Update()
writer = vtk.vtkXMLRectilinearGridWriter()
writer.SetInputData(transformFilter.GetOutput())
writer.SetFileName("Output.vtr")
writer.Update()
Now I don't get any errors but also there is no file created and I don't know where I go wrong. Any help is highly appreciated.
(btw I tried this answer and that actually does create a file)
EDIT; Maybe I found why it goes wrong but still I don't know how to fix it. If I print data it says vtkRectilinearGrid while if I print transformFilter.GetOutput() it says vtkStructuredGrid. I thought the transform filter would keep the same grid type but apparantly not. Somebody any idea to let it keep the same grid type?
A vtkRectilinearGrid is oriented along the main axis. It allows some optimizations, like having implicit coordinates.
The output of the Transform filter cannot be converted to a vtkRectlinearGrid, mainly because you cannot assume its orientation. Points cannot be implicit as with the RectilinearGrid, the object store each of them.
As you said, your solution is to change how you write your data. You can write a .vts file with a vtkXMLStructuredGridWriter.

Interpolation between two keys makes are off after python importantion

I'm trying to import an animation from a file to Maya, but it gives me odd results between the interpolations:
https://i.imgur.com/cP27Yai.mp4
It was weird because they keyframes looked right at first until i looked at the graph editor.
thought this was at first a gimbal lock, so i used the Euler Filter, but it gave no solution to it. Sometimes, the difference between one key and another is 180, which is why, by just seeing the animation, the keys look fine, but the interpolation makes it do a 180 rotation.
So if i go one by one, and subtract the vaule of the key by 180, and then invert the number (to positive or negative depending on the case), i can make it work by tweaking it a bit.
However this is too much work, specially for being biped animations, it could took me forever.
Is this a common issue or something that happened before to anyone else? Is there any way to fix this? Maybe it's the way i'm applying the euler angles, since they were initially Quaternions, but i did not find a way to apply the quaternions directly:
#Taking a rotation from the QUATERNION Array and converting it to Euler.
arot = anim.AnimRot[index].normal().asEulerRotation()
frot = MEulerRotation(arot.x*180/math.pi, arot.y*180/math.pi, arot.z*180/math.pi)
cmds.setAttr((obj + ".rotate"), frot.x, frot.y, frot.z)
cmds.setKeyframe(obj, time=anim.TotalKeys[i])
Is there any way to fix this from the editor or the script? any that fixes it would do me a great favor for importing this biped animation. I believe this is due to euler conversion, but i found no way to apply a quaternion to a bone in the maya API.
If the rotations already are quaternions, you might want to simply set the anim curves to quaternion interpolation using something like
cmds.rotationInterpolation( 'pSphere2.rotateX', 'pSphere2.rotateY', 'pSphere2.rotateZ', c="quaternionSquad")
To be safe I'd set one key, then apply the rotationInterpolation to change the keys to quats, then step through applying your original quaternions. Since you're already in API land you can make an MTransformationMatrix and use its setRotationComponents method to set the quat values so you don't ever convert to eulers.

Python graph like windirstat?

I'm interested in using python to make diagrams representing the size of values based on the size of squares (and optionally their colour). Basically I'm looking for a way to make overviews of a bunch of values like the good old program windirstat does with hard-drive usage (it basically makes a big square representing your harddrive and then smaller squares making up the area inside of it representing different programs, the bigger the square the larger the file, colour indicates the type of file). I'm fairly familiar with matplotlib, and I don't think it's possible to do something like this with it. Is there any other python package that would help? Any suggestions for something more low level if it's not? I guess I could do it manually if I could find a way to draw the boxes programatically (I don't really care about the format, but the option to export SVG as well as PNG would be nice).
Ultimately, it would be nice to have it be interactive like windirstat is, where if you were to hover over a particular square you get more information on it, and if you clicked on it maybe you'd go in and see the makeup of that particular square. I'm only familiar with wxpython for GUI stuff, not sure if it could be used for something like this. For now I'd be happy with just outputting them though.
Thanks a lot!
Alex
Edit:
Thanks guys, both your answers helped a lot.
You're looking for Treemapping algorithms. Once implemented, you can transform the output (which should be rectangles) into plotting commands to anything that can draw layered rectangles.
Edit:
More links and information:
If you don't mind reading papers, the browser-based d3 library provides for 'squarified' treemaps (js implementation). They reference this paper by Bruls, Huizing, and van Wijk. (This is also citation 3 on the wikipedia article)
I'd search on the algorithms listed on the linked Wikipedia article. For instance, they also link to this article, which describes an algorithm for "mixed treemaps". The paper also includes some interesting portions at the end describing transformations into other-than-rectangular shapes.
Squarified certainly appears to be the most common variety around. The above links should give you enough to work towards a solution or, even, directly port the d3 implementation. However, the cost of grokking d3's model (which is something like a declarative form of jQuery) may be somewhat high. At first glance, though, the implementation appears relatively straightforward.
Squaremap does this. I haven't used it (I only know it from RunSnakeRun) and its documentation is severely lacking, but it seems to work.

Graph colouring in python using adjacency matrix

How can I implement graph colouring in python using adjacency matrix? Is it possible? I implemented it using list. But it has some problems. I want to implement it using matrix. Can anybody give me the answer or suggestions to this?
Is it possible? Yes, of course. But are your problems with making Graphs, or coding algorithms that deal with them?
Separating the algorithm from the data type might make it easier for you. Here are a couple suggestions:
create (or use) an abstract data type Graph
code the coloring algorithm against the Graph interface
then, vary the Graph implementation between list and matrix forms
If you just want to use Graphs, and don't need to implement them yourself, a quick Google search turned up this python graph library.
Implementing using adjacency is somewhat easier than using lists, as lists take a longer time and space. igraph has a quick method neighbors which can be used. However, with adjacency matrix alone, we can come up with our own graph coloring version which may not result in using minimum chromatic number. A quick strategy may be as follows:
Initalize: Put one distinct color for nodes on each row (where a 1 appears)
Start: With highest degree node (HDN) row as a reference, compare each row (meaning each node) with the HDN and see if it is also its neighbor by detecting a 1. If yes, then change that nodes color. Proceed like this to fine-tune. O(N^2) approach! Hope this helps.

Game map from Code

It's a long one so you might want to get that cup of tea/coffee you've been holding off on ;)
I run a game called World of Arl, it's a turn based strategy game akin to Risk or Diplomacy. Each player has a set of cities, armies and whatnot. The question revolves around the display of these things. Currently the map is created using a background image with CSS positioning of team icons on top of that to represent cities. You can see how it looks here: WoA Map
The background image for the map is located here: Map background and created in Omnigraffle. It's not designed to draw maps but I'm hopelessly incompetent with photoshop and this works for my purposes just fine.
The problem comes that I want to perform such fun things as pathfinding and for that I need to have the map somehow stored in code. I have tried using PIL, I have looked at incorporating it with Blender, I tried going "old school" and creating tiles as from many older games and finally I tried to use SVG. I say this so you can see clearly that it's not through lack of trying that I have this problem ;)
I want to be able to store the map layout in code and both create an image from it and use it for things such as pathfinding. I'm using Python but I suspect that most answers will be generic. The cities other such things are stored already and easily drawn on, I want to store the layout of the landmass and features on the landmass.
As for pathfinding, each type of terrain has a movement cost and when the map is stored as just an image I can't access the terrain of a given area. In addition to pathfinding I wish to be able to know the terrain for various things related to the game, cities in mountains produce stone for example.
Is there a good way to do this and what terms should I have used in Google because the terms I tried all came up with unrelated stuff (mapping being something completely different most of the time).
Edit 2:
Armies can be placed anywhere on the map as can cities, well, anywhere but in the water where they'd sink, drown and probably complain (in that order).
After chatting to somebody on MSN who made me go over the really minute details and who has a better understanding of the game (owing to the fact that he's played it) it's occurring to me that tiles are the way to go but not the way I had initially thought. I put the bitmap down as it is now but also have a data layer of tiles, each tile has a given terrain type and thus pathfinding and suchlike can be done on it yet at the same time I still render using Omnigraffle which works pretty well.
I will be making an editor for this as suggested by Adam Smith. I don't know that graphs will be relevant Xynth but I've not had a chance to look into them fully yet.
I really appreciate all those that answered my question, thanks.
I'd store a game map in code as a graph.
Each node would represent a country/city and each edge would represent adjacency. Once you have a map like that, I'm sure you can find many resources on AI (pathfinding, strategy, etc.) online.
If you want to be able to build an image of the map programattically, consider adding an (x, y) coordinate and an image for each node. That way you can display all of the images at the given coordinates to build up a map view.
The key thing to realize here is that you don't have to use just one map. You can use two maps:
The one you already have which is drawn on screen
A hidden map which isn't drawn but which is used for path finding, collision detection etc.
The natural next question then is where does this second map come from? Easy, you create your own tool which can load your first map, and display it. Your tool will then let you draw boundaries around you islands and place markers at your cities. These markers and boundaries (simple polygons e.g.) are stored as your second map and is used in your code to do path finding etc.
In fact you can have your tool emit python code which creates the graphs and polygons so that you don't have to load any data yourself.
I am just basically telling you to make a level editor. It isn't very hard to do. You just need some buttons to click on to define what you are adding. e.g. if you are adding a polygon. Then you can just add each mouse coordinate to an array each time you click on your mouse if you have toggled your add polygon button. You can have another button for adding cities so that each time you click on the map you will record that coordinate for the city and possibly a corresponding name that you can provide in a text box.
You're going to have to translate your map into an abstract representation of some kind. Either a grid (hex or square) or a graph as xynth suggests. That's the only way you're going to be able to apply things like pathfinding algorithms to it.
IMO, the map should be rendered in the first place instead of being a bitmap. What you should be doing is to have separate objects each knowing its dimensions clearly such as a generic Area class and classes like City, Town etc derived from this class. Your objects should have all the information about their location, their terrain etc and should be rendered/painted etc. This way you will have exact knowledge of where everything lies.
Another option is to keep the bitmap as it is and keep this information in your objects as their data. By doing this the objects won't have a draw function but they will have precise information of their placement etc. This is sort of duplicating the data but if you want to go with the bitmap option, I can't think of any other way.
If you just want to do e.g. 2D hit-testing on the map, then storing it yourself is fine. There are a few possibilities for how you can store the information:
A polygon per island
Representing each island as union of a list rectangles (commonly used by windowing systems)
Creating a special (maybe greyscale) bitmap of the map which uses a unique solid colour for each island
Something more complex (perhaps whatever Omnigiraffe's internal representation is)
Asuming the map is fixed (not created on the fly) its "correct" to use a bitmap as graphical representation - you want to make it as pretty as possible.
For any game related features such as pathfinding or whatever fancy stuff you want to add you should add adequate data structures, even if that means some data is redundant.
E.g. describe the boundaries of the isles as polygon splines (either manually or automatically created from the bitmap, thats up to you and how much effort you want to spend and is needed to get the functionality you want).
To sum it up: create data structures matching the problems you have to solve, the bitmap is fine for looks but avoid doing pathfining or other stuff on it.

Categories