How to remove duplicate vertices and their vertex handles when performing hole filling in OpenFlipper based on OpenMesh - duplicates

Recently, I am using the plugin "hole filling" of OpenFlipper, and have entirely compiled the OpenFlipper. However, the new mesh has a large number of duplicate vertices, when I tried to add the filling patch to the original mesh. I used the following codes to perform the adding operation:
// filling_patch: newly created filling mesh
// mesh_ori: the original mesh before hole filling
class MeshT::FaceHandle fh;
class MeshT::FaceIter f_it, f_end;
class MeshT::FaceVertexIter fv_it;
for(f_it = filling_patch->faces_begin(), f_end = fill_patch ->faces_end(); f_it != f_end; f_it++)
{
// ith face
fh = *f_it;
// Check whether it is valid
if(!fh.is_valid())
{
return;
}
// Store its three vertices
std::vector<class MeshT::VertexHandle> face_vhandles;
face_vhandles.clear();
// Iterate each vertex of this face
for(fv_it = mesh_ori->fv_iter(fh); fv_it.is_valid(); fv_it++)
{
// Get the 3D point
class MeshT::Point p = filling_patch->point(*fv_it);
// Add this point to original mesh. Note: vh is a new vertevHandle, differ to *fv_it
class MeshT::VertexHandle vh = mesh_ori->add_vertex(p);
face_vhandles.push_back(vh);
}
// Save the face to mesh
mesh_ori->add_face(face_vhandles);
}
So, I am not sure whether there is an existing function that can be used to fix this problem in OpenMesh.
Does someone give me some advice?
Thanks a lot.

Related

as3 add multiple MovieClips into random MovieClips

I'm trying to to do some dynamic MovieClips placement here. I've been trying for a couple'o days and I can't find the right way to do the trick. It's the continuation for this. I didn't manage to properly make my MC's appear in the triangle, so I've made a pyramid of rectangles (suits my case better, beacuse I can change each of'em, to better fit my desired shape - a not-so-regular triangle).
Here's the code with some comments:
import flash.events.MouseEvent;
import flash.display.MovieClip;
btn_toys_2.confirm.addEventListener(MouseEvent.MOUSE_UP, confirmToys);
var toysPlc:Array = new Array(); //an array for a bunch of rectangles
var toAdd:int = 100 //this is supposed to be dynamic, user defined
var toy:MovieClip = new shar_001; //an MC from a library
for (var j:int=0; j<33; j++){
toysPlc.push("tPl_" + j); //here I add that bunch of rects into an array
}
function confirmToys(e:MouseEvent):void{
for (var k:int=0; k<toAdd; k++){ //supposed to add an "toAdd" amount of "toys"
var p:int = Math.random()*toysPlc.length; //^do so in a random rect
toysPlc[p].addChild(toy); //supposed to place a toy in a random rect
toy.x = Math.random()*toysPlc[p].width; //positioning
toy.y = Math.random()*toysPlc[p].height; //positioning
}
}
The error I get is: TypeError: Error #1006: value is not a function.
What I DID manage is to place a single toy in a random of these rects, tho I don't remember how :)
Thanks in advance!
EDIT: null asked me to clarify the case, so here's the whole picture:
I've got:
- triangle-like MC (since a triangle MC is a rectangle for flash anyway, I've solved this by creating a pyramid of 33 rectangles, layered on each other);
- toys (multiple frames to change whenever I need to);
- text field (to input the quantity of desired toys);
- confirm button (to make the magic happen once clicked);
Now I need a user to input a 3-digit number in the input field, press "confirm", and 0.4 of that quantity is supposed to appear in the "triangle-like MC".
For example: user inputs a number: 600, the end value is 600*0.4=240. Now 240 "toys" are randomly spreaded between my 33 rectangles, within their width (which is different for every single one).
Hope that explains a bit more.
A simplified sample of what I need here.
Is there a way to fill an array with MovieClips rather than String values? That would be THE answer to this question here.
There is in fact more than one way:
Place all the instance names into the Array when you create it:
var rectangles:Array = [instanceName1, instanceName2];
there are no quotation marks, which create string literals. Just the names.
This approach quickly becomes impractical for large numbers of objects.
Given that the instance names have a number component, iterate through the names in conjunction with getChildByName(). I assume that this is what you were trying with in your question:
var rectangles:Array = []; // initialise empty array
for (var j:int=0; j<33; j++){
rectangles.push(getChildByName("tPl_" + j));
}
original answer
toysPlc.push("tPl_" + j); //here I add that bunch of rects into an array
No you don't. You are filling the Array with String objects. It's totally unrelated to any rectangle whatsoever.
Now this next line, tries to call a function on each String, which fails.
toysPlc[p].addChild(toy);
The above is equivalent to
"tPl_0".addChild(toy);
"tPl_1".addChild(toy);
// etc.
A String doesn't have that method addChild.

Moving 3D charracter - I don't want any physics, expected of collisions, and gravity

I am working on a game. I constructed my player as here: (I am using a gravity on my world)
private ArrayMap<String, GameObject.Constructor> constructors = new ArrayMap<String, GameObject.Constructor>(String.class, GameObject.Constructor.class);
private ArrayList<GameObject> instances = new ArrayList<GameObject>();
assets.load("hand.obj", Model.class);
...
model = assets.get("hand.obj", Model.class);
constructors.put("hand", new GameObject.Constructor(model, new btBoxShape(new Vector3(2.5f, 7.5f, 2.5f)), 1f));
...
hand = constructors.get("hand").construct(); // that construct method returns me model, shape and constructions.. the GameObject extends ModelInstance, so i can use it like a modelinstance
hand.transform.setToTranslation(x, y, z);
hand.body.proceedToTransform(hand.transform);
hand.body.setUserValue(instances.size());
hand.body.setCollisionFlags(hand.body.getCollisionFlags()| btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
world.addRigidBody(hand.body);
hand.body.setContactCallbackFlag(OBJECT_FLAG);
hand.body.setContactCallbackFilter(OBJECT_FLAG);
Then, in render method I am moving it:
if (!hand.body.isActive()) hand.body.activate();
if (Gdx.input.isKeyPressed(Keys.W)){
hand.body.translate(new Vector3(0,0,-1));
}
else if (Gdx.input.isKeyPressed(Keys.S)) {
hand.body.translate(new Vector3(0,0,+1));
}
That's nice! The moving now works good, when I am moving at the flat ground. Whenever there is an object before me, it is not as expected. Because my player shape is biger than
object shape (which is 2.5f, 2.5f, 2.5f), it kind of falls on it. So I would like to set the rotation to be still the same, so the object will not be rotating (so it will not "fall" on the object before). And so I tried to do it, and I failed. Because there are functions like rotate, and I want to something like setRotation
. And so, there is a setToRotation, but you can not pass there a Quaternion.
I need help. I tried to use a btKinematicCharacterController but it was bad. The ghostObject every time falled through object, but the objects got a collision from him.
and so I want to create a player movment, like in games like Wow, minecraft, and so on.
I looked at the btKinematicCharacterController again. The reason why my ghostobject falled through the ground was. Generally, I don't know the reason: D probably I was using another broadphase for ghost, that for world. This line fixes it: characterController.setUseGhostSweepTest(false);
and I am getting another problem, when I am walking on my ground (a lot of objects), the character is getting to lesser Y position. I don't know why.
Here is my construction:
btPairCachingGhostObject ghostObject;
btConvexShape ghostShape;
btKinematicCharacterController characterController;
Vector3 characterDirection = new Vector3();
Vector3 walkDirection = new Vector3();
...
ghostObject = new btPairCachingGhostObject();
ghostObject.setWorldTransform(hand.transform);
ghostShape = new btCapsuleShape(5f, 0.5f);
ghostObject.setCollisionShape(ghostShape);
ghostObject.setCollisionFlags(btCollisionObject.CollisionFlags.CF_CHARACTER_OBJECT);
characterController = new btKinematicCharacterController(ghostObject, ghostShape, .00001f);
// And add it to the physics world
characterController.setUseGhostSweepTest(false);
world.addCollisionObject(ghostObject,
(short)btBroadphaseProxy.CollisionFilterGroups.CharacterFilter,
(short)(btBroadphaseProxy.CollisionFilterGroups.StaticFilter | btBroadphaseProxy.CollisionFilterGroups.DefaultFilter));
world.addAction(characterController);
... (in render - moving)
if (!load)
{
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
hand.transform.rotate(0, 1, 0, 5f);
ghostObject.setWorldTransform(hand.transform);
}
if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
hand.transform.rotate(0, 1, 0, -5f);
ghostObject.setWorldTransform(hand.transform);
}
// Fetch which direction the character is facing now
characterDirection.set(-1,0,0).rot(hand.transform).nor();
// Set the walking direction accordingly (either forward or backward)
walkDirection.set(0,0,0);
if (Gdx.input.isKeyPressed(Keys.UP))
walkDirection.add(characterDirection);
if (Gdx.input.isKeyPressed(Keys.DOWN))
walkDirection.add(-characterDirection.x, -characterDirection.y, -characterDirection.z);
walkDirection.scl(4f * Gdx.graphics.getDeltaTime());
// And update the character controller
characterController.setWalkDirection(walkDirection);
// And fetch the new transformation of the character (this will make the model be rendered correctly)
}
world.stepSimulation(delta, 5, 1f/60f);
if (!load)
ghostObject.getWorldTransform(hand.transform);
How to fix this?
I set up the debugDrawer, so i was able to see the shapes of the bullet objects.. and my problem was that: the ghostObject(charController) was pushing my objects down.. Although my objects were static. So i set the mass of the objects to 0 and problem is fixed. But I still dont know, how it could push static objects. But i dont care. :)
EDIT: i will accept this answer in 2 hours, because now i cant.

How to determine whether a given object is a mask

Apparently, in Adobe's wisdom, both the object being mask, and the masking object contain a "mask" property. This leads to a cyclical reference that prevents determining which is the actual mask and which is the masked.
For example...
var clip:MovieClip = new MovieClip();
clip.name = "clip";
addChild(clip);
var boundary:Shape = new Shape();
boundary.name = "boundary";
clip.addChild(boundary);
clip.mask = boundary;
trace(clip.mask.name); // outputs "boundary"
trace(clip.mask.mask.name); // outputs "clip"
I've iterated through the properties of both clip and boundary, and there doesn't seem to be anything unique that sets them apart. My first thought was to force a removal of the superfluous "mask" reference in boundary, however, that also sets the mask property in clip to null, thereby removing the mask.
My second thought was to check the parent relationship of a mask. If the parent is the same as the object's mask, then the object in question is itself the mask.
var a:Array = [clip, boundary];
for each (var item in a) {
if (item.mask == item.parent) {
trace(item.name + " is a mask");
}
}
// outputs "boundary is a mask"
Seems to work, and after checking the API reference on masks, it's clear that when caching, a mask will need to be a child of the masked, however... it's also valid to have a mask at the same depth as the masked (I do this from time to time when a mask needs to not travel with the masked content).
For example...
MainTimeline ¬
0: clip ¬
0: boundary
... can also be laid out as ...
MainTimeline ¬
0: clip ¬
1: boundary
So, there's the conundrum. Any ideas on how to resolve this?
The "best" hack I've found so far is to run hitTestPoint on the objects (after making sure they have something to hit under the target). Masks do not appear to ever return true for a full pixel hit test. This seems to work in most basic situations that I've tested:
public function isMask(displayObject:DisplayObject):Boolean {
// Make sure the display object is a Class which has Graphics available,
// and is part of a mask / maskee pair.
if ((displayObject is Shape || displayObject is Sprite) && displayObject.mask) {
// Add a circle at the target object's origin.
displayObject['graphics'].beginFill(0);
displayObject['graphics'].drawCircle(0, 0, 10);
var origin:Point = displayObject.localToGlobal(new Point());
var maskLocal:Point = displayObject.mask.globalToLocal(origin);
// Add a circle at the same relative position on the "mask".
displayObject.mask['graphics'].beginFill(0);
displayObject.mask['graphics'].drawCircle(maskLocal.x, maskLocal.y, 10);
// No matter which is the actual mask, one circle will reveal the other,
// so hit testing the origin point should return true.
// However, it seems to return false if the object is actually a mask.
var hit:Boolean = displayObject.hitTestPoint(origin.x, origin.y, true);
displayObject['graphics'].clear();
displayObject.mask['graphics'].clear();
// Return true if the hit test failed.
return !hit;
} else {
return false;
}
}
Obviously you'd want to cache the graphics in case the objects already have some, and it could do with something more elegant than casting as Sprite so that it can handle Shapes, but it's a start.
Edit: Accessing ['graphics'] lets this accept Shapes, but obviously isn't super efficient. I'm not sure what the best method would be, short of adding an interface.
Great question, haven't run into this before. I wasn't aware of the cyclical reference.
If your masks are exclusively masks, I would suggest just incorporating that into your naming convention. For example calling it clipMask as opposed to boundary.
As noted in the comments, in the situation where the mask is on the same display list, you could use getChildIndex() to compare their position on the display list of the parent.
Typically in that situation I'll have the mask layered over the other display object. This is not enforced obviously, and I don't believe that it has any effect on the result of the mask visually. But it's easier to maintain for a large group than a naming convention.
Still not ideal obviously.

How can I optimise this method?

I have been working on creating an assets class that can generate dynamic TextureAtlas objects whenever I need them. The specific method is Assets.generateTextureAtlas() and I am trying to optimise it as much as possible as I quite frequently need to regenerate texture atlas's and was hoping to get a better time than my 53ms average.
53ms is currently costing me about 3 frames which can add up quickly the more items I need to pack inside my texture atlas and the frequency I need to generate them. So an answer to all the pitfalls within my code would be great.
The entire class code is available here in a github gist.
The RectanglePacker class is simply used to pack rectangles as close together as possible (similar to Texture Packer) and can be found here.
For reference, here is the method:
public static function generateTextureAtlas(folder:String):void
{
if (!_initialised) throw new Error("Assets class not initialised.");
if (_renderTextureAtlases[folder] != null)
{
(_renderTextureAtlases[folder] as TextureAtlas).dispose();
}
var i:int;
var image:Image = new Image(_blankTexture);
var itemName:String;
var itemNames:Vector.<String> = Assets.getNames(folder + "/");
var itemsTexture:RenderTexture;
var itemTexture:Texture;
var itemTextures:Vector.<Texture> = Assets.getTextures(folder + "/");
var noOfRectangles:int;
var rect:Rectangle;
var rectanglePacker:RectanglePacker = new RectanglePacker();
var texture:Texture;
noOfRectangles = itemTextures.length;
if (noOfRectangles == 0)
{
return;
}
for (i = 0; i < noOfRectangles; i++)
{
rectanglePacker.insertRectangle(Math.round(itemTextures[i].width), Math.round(itemTextures[i].height), i);
}
rectanglePacker.packRectangles();
if (rectanglePacker.rectangleCount != noOfRectangles)
{
throw new Error("Only " + rectanglePacker.rectangleCount + " out of " + noOfRectangles + " rectangles packed for folder: " + folder);
}
itemsTexture = new RenderTexture(rectanglePacker.width, rectanglePacker.height);
itemsTexture.drawBundled(function():void
{
for (i = 0; i < noOfRectangles; i++)
{
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i, rect);
image.texture = itemTexture;
image.readjustSize();
image.x = rect.x + itemTexture.frame.x;
image.y = rect.y + itemTexture.frame.y;
itemsTexture.draw(image);
}
});
_renderTextureAtlases[folder] = new TextureAtlas(itemsTexture);
for (i = 0; i < noOfRectangles; i++)
{
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
(_renderTextureAtlases[folder] as TextureAtlas).addRegion(itemName, rect, itemTexture.frame);
}
}
Well reading the project & finding what all can be optimized would sure take time.
Start by removing multiple calls to rectanglePacker.getRectangle(i) inside loops.
For example :
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
perhaps, could have been:
rect = rectanglePacker.getRectangle(i);
itemName = itemNames[rect];
itemTexture = itemTextures[rect];
If getRectangle does indeed just 'get a rectangle' & not set anything.
I think the bigger issue at hand is this, why oh why do you HAVE to do this during run-time, in a situation when this can't take more time? This IS an expansive operation, no matter how much you optimize this you will probably end up with it taking about 40ms or similar when done in AS3.
This is why these kind of operations should be done during compile time or during "loading screens" or other "transitions" when frame-rate is not critical and when you can afford it.
Alternatively create another system in c++ or some other language which can actually handle the number-crunching that gives you the finished result.
Also, when it comes to checking performance, yes the entire function takes 53ms, BUT, where are those milliseconds used? 53ms says nothing and is only the "overhead profiling thing" where you found the culprit, you need to break it down into smaller chunks to gather some reliable information about what it is that ACTUALLY takes time, inside that function.
I mean, inside that function, you have 3 for loops, several calls to other classes, casts, deletes, creations. It's not like you are doing one thing, that function probably results in ~500 lines of code and a bazillion cpu operations. And, you have no idea where it is used. I would guess that it is the rectanglePacker.packRectangles(); that takes 60% of that time, but without profiling, you and we don't know on what to optimize, we simply don't have sufficient data.
If you HAVE to do this during run-time in AS3, I would recommend doing this spread out during several frames and distributing workload evenly during 10 frames or so. You could also doing it with help of another thread and workers. But most of all, this seems like a design error since this could probably be done at another time. And if not, then in another language which is better at these kind of operations.
The easiest way to profile this is to add a couple of timestamps similar to:
var timestamps:Array = [];
And then push getTimer() at different places in code, and then print them out when function is done
As others said, it's unlikely that the reason of bad performance is non-optimized AS code. Output from the profiler (Scout, for example) wold be very helpful. However, if your purpose is just adding new textures, I can suggest several optimizations:
Why would you need to re-generate the whole atlas every time (calling Assets.getTextures() and creating new render texture)? Why don't you just add new items to the existing atlas? Creation of a new RenderTexture (and, thus, a new texture in GPU memory) is very costly operation, because it requires sync between CPU and GPU. On the other hand, drawing into RenderTexture is carried out entirely inside GPU, so it takes much less time.
If you place every item on a grid, then you can avoid using RectanglePacker as all of your rectangles can have the same dimensions matching the dimensions of a grid.
Edit:
To clarify, some time ago I had a similar problem: I had to add new items to the existing atlas on a regular basis. And the performance of this operation was quite acceptable (about 8ms on iPad3 using 1024x1024 dynamic texture). But I used the same RenderTexture and the same Sprite object that contained my dynamic atlas items. When I need to add a new item, I just create new Image with desired texture (stand-alone or from another static atlas), then place it inside the Sprite container, and then redraw this container to the RenderTexture. Similarly with deletion/modification of an item.

Is there a way to get the actual bounding box of a glyph in ActionScript?

I'm learning ActionScript/Flash. I love to play with text, and have done a lot of that kind of thing with the superb Java2D API.
One of the things I like to know is "where, exactly, are you drawing that glyph?" The TextField class provides the methods getBounds and getCharBoundaries, but these methods return rectangles that extend far beyond the actual bounds of the whole text object or the individual character, respectively.
var b:Sprite = new Sprite();
b.graphics.lineStyle(1,0xFF0000);
var r:Rectangle = text.getCharBoundaries(4);
r.offset(text.x, text.y);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);
b = new Sprite();
b.graphics.lineStyle(1,0x00FF00);
r = text.getBounds(this);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);
Is there any way to get more precise information about the actual visual bounds of text glyphs in ActionScript?
Richard is on the right track, but BitmapData.getColorBounds() is much faster and accurate... I've used it a couple of times, and optimized for your specific needs its not as slow as one might think.
Cory's suggestion of using flash.text.engine is probably the "correct" way to go, but I warn you that flash.text.engine is VERY (very!) hard to use compared to TextField.
Not reasonably possible in Flash 9 -- Richard's answer is a clever work-around, though probably completely unsuitable for production code (as he mentions) :)
If you have access to Flash 10, check out the new text engine classes, particularly TextLine.
I'm afraid all the methods that are available on TextField are supposed to do what you have already found them to do. Unless performance is key in your application (i.e. unless you intend to do this very often) maybe one option would be to draw the text field to a BitmapData, and find the topmost, leftmost, et c colored pixels within the bounding box retrieved by getCharBoundaries()?
var i : int;
var rect : Rectangle;
var top_left : Point;
var btm_right : Point;
var bmp : BitmapData = new BitmapData(tf.width, tf.height, false, 0xffffff);
bmp.draw(tf);
rect = tf.getCharBoundaries(4);
top_left = new Point(Infinity, Infinity);
btm_right = new Point(-Infinity, -Infinity);
for (i=rect.x; i<rect.right; i++) {
var j : int;
for (j=rect.y; j<rect.bottom; j++) {
var px : uint = bmp.getPixel(i, j);
// Check if pixel is black, i.e. belongs to glyph, and if so, whether it
// extends the previous bounds
if (px == 0) {
top_left.x = Math.min(top_left.x, i);
top_left.y = Math.min(top_left.y, j);
btm_right.x = Math.max(btm_right.x, i);
btm_right.y = Math.max(btm_right.y, j);
}
}
}
var actualRect : Rectangle = new Rectangle(top_left.x, top_left.y);
actualRect.width = btm_right.x - top_left.x;
actualRect.height = btm_right.y - top_left.y;
This code should loop through all the pixels that were deemed part of the glyph rectangle by getCharBoundaries(). If a pixel is not black, it gets discarded. If black, the code checks whether the pixels extends further up, down, right or left than any pixel that has previuosly been checked in the loop.
Obviously, this is not optimal code, with nested loops and unnecessary point objects. Hopefully though, the code is readable enough, and you are able to make out the parts that can most easily be optimized.
You might also want to introduce some threshold value instead of ignoring any pixel that is not pitch black.