I've constructed a quick python script that reads a wavefront .obj file and outputs the verticies and faces to files. I have another C++ function that reads these files and creates a mesh based of-of those.
The issue that I'm experiencing is that this works perfectly sometimes, and other time not so much - with the same mesh. E.g. I start my PhysX program, and create 10 of the same objects of the same mesh and some of them look like this:
and others look like this:
The following C++ is the code that loads the verticies and triangles:
bool ModelLoader::LoadVertexFile(const std::string& fileLocation)
{
std::ifstream file(fileLocation);
if (!file) {
std::cerr << "Failed to load vertex data\n";
return false;
}
float x, y, z;
vertexArray.clear();
while (file >> x >> y >> z)
{
vertexArray.push_back(PhysicsEngine::PxVec3(x, y, z));
}
return true;
}
bool ModelLoader::LoadTrianglesFile(const std::string& fileLocation)
{
std::ifstream file(fileLocation);
if (!file) {
std::cerr << "Failed to load vertex data\n";
return false;
}
int x;
triangleArray.clear();
while (file >> x)
{
triangleArray.push_back(x);
}
return true;
}
This is the code for creating constructing the mesh
CustomObject(const PxTransform& pose = PxTransform(PxIdentity), string vertfile = "", string trigfile = "") :
StaticActor(pose)
{
modelLoader = new ModelLoader();
if(!modelLoader->LoadVertexFile(vertfile))
throw new Exception("Failed to load VertexFile.");
if(!modelLoader->LoadTrianglesFile(trigfile))
throw new Exception("Failed to load TrianglesFile.");
PxTriangleMeshDesc mesh_desc;
mesh_desc.points.count = (PxU32)modelLoader->vertexArray.size();
mesh_desc.points.stride = sizeof(PxVec3);
mesh_desc.points.data = &modelLoader->vertexArray.front();
mesh_desc.triangles.count = (PxU32)modelLoader->triangleArray.size();
mesh_desc.triangles.stride = 3 * sizeof(PxU32);
mesh_desc.triangles.data = &modelLoader->triangleArray.front();
CreateShape(PxTriangleMeshGeometry(CookMesh(mesh_desc)));
}
So if anyone can help me figure out whats going wrong it would be really appreciated
Related
First off, I'm aware of the CGAL GIS tutorial, but I just can't seem to copy properties from Point_set to surface mesh.
Any way, I'm loading the LIDAR point cloud to the point set as follows:
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point = Kernel::Point_3;
using Point_set = CGAL::Point_set_3<Point>;
std::ifstream ifile("input.ply", std::ios_base::binary);
ifile >> point_set;
std::cerr << point_set.size() << " point(s) read" << std::endl;
ifile.close();
I can get the properties via
auto props = point_set.properties();
for (const auto& item : props)
std::cerr << item << std::endl;
// I do know that there exist property "classification" that is of unsigned char type
Point_set::Property_map<unsigned char> original_class_map
= point_set.property_map<unsigned char>("classification").first;
Then, I had tried to set the mesh and had added vertex property, using the code from above mentioned CGAL tutorial. The code below set the point's z coordinate as a property.
auto idx_to_point_with_info
= [&](const Point_set::Index& idx) -> std::pair<Point, Point_set::Index> {
return std::make_pair(point_set.point(idx), idx);
};
using Vbi = CGAL::Triangulation_vertex_base_with_info_2<Point_set::Index, Projection_traits>;
using Fbi = CGAL::Triangulation_face_base_with_info_2<int, Projection_traits>;
using TDS = CGAL::Triangulation_data_structure_2<Vbi, Fbi>;
using TIN_with_info = CGAL::Delaunay_triangulation_2<Projection_traits, TDS>;
TIN_with_info tin_with_info(
boost::make_transform_iterator(point_set.begin(), idx_to_point_with_info),
boost::make_transform_iterator(point_set.end(), idx_to_point_with_info));
auto classification_value = [&](const TIN_with_info::Vertex_handle vh) -> double
{
return vh->point().z();
};
for (TIN_with_info::Vertex_handle vh : tin_with_info.all_vertex_handles())
{ // should work without classification_value, just plain vh->info() = vh->point().z();
vh->info() = classification_value(vh);
}
using Mesh = CGAL::Surface_mesh<Point>;
Mesh tin_class_mesh;
Mesh::Property_map<Mesh::Vertex_index, double> class_map
= tin_class_mesh.add_property_map<Mesh::Vertex_index, double>("v:class").first;
CGAL::copy_face_graph(tin_with_info, tin_class_mesh,
CGAL::parameters::vertex_to_vertex_output_iterator(
boost::make_function_output_iterator(class_lambda)));
std::cerr << tin_class_mesh.number_of_vertices() << " vs " << point_set.size() <<std::endl;
Now, this works just fine, I had successfully set the z coordinate as a property on a mesh.
But, I just can't figure out how can I copy the classification property from the point_set to the tin_class_mesh. I know that I'd need to change double to unsigned char in the code, but I don't know how to access the property from the point_set and assign it to the corresponding vertex in tin_class_mesh. What am I doing wrong?
As a side note, the interesting part here is that the number of tin_colored_mesh.number_of_vertices() differs slightly from the point_set.size(). Why is that?
I have a directory Processed_Data with thousands of hists*****_blinded.root files. Each hists*****_blinded.root contains around 15 graphs and histograms in it. My goal is just to overlap 1 specific histogram sc***** from each file to get the final histogram finalhists_blinded.root which will represent all of those overlapped together.
I have tried the following macro:
void final()
{
TCanvas *time = new TCanvas("c1","overlap" ,600,1000);
time ->Divide(1,1);
time ->cd(1);
TH1F *h1 = new TH1F("h1","time" ,4096,0,4096);
ifstream in;
Float_t t;
Int_t nlines= 0;
in.open("Processed_Data", ios::in);
while (1) {
in >> t;
if (!in.good()) break;
h1->Fill(t);
nlines++;
}
in.close();
But I get the blank canvas at the end. The idea is to run each hists file through the code and add each one by one.
As a result, I want to see all those sc***** histograms overlapping so that the spikes in each of them will create a pattern in a finalhists_blinded.root file.
Shouldn't be that complicated, try this:
void overlap()
{
TCanvas *time = new TCanvas("c1", "overlap", 0, 0, 800, 600);
const char* histoname = "sc";
const int NFiles = 100000;
for (int fileNumber = 0; fileNumber < NFiles; fileNumber++)
{
TFile* myFile = TFile::Open(Form("Processed_Data/hists%i_blinded.root", fileNumber));
if (!myFile)
{
printf("Nope, no such file!\n");
return;
}
TH1* h1 = (TH1*)myFile->Get(histoname);
if (!h1)
{
printf("Nope, no such histogram!\n");
return;
}
h1->SetDirectory(gROOT);
h1->Draw("same");
myFile->Close();
}
}
It loops over all Processed_Data/histsXXXXXi_blinded.root files (given their names are Processed_Data/hists0_blinded.root, Processed_Data/hists1_blinded.root, Processed_Data/hists2_blinded.root, ..., Processed_Data/hists99998_blinded.root, Processed_Data/hists99999_blinded.root), opens each of them, grabs a 1D sc histogram, adds it to the canvas, closes the file and moves to the next file.
In order to read all shapes within my step file, I have succeed to extract all shapes using STEPControl_reader.
Now I want to find a way (OCAF/XDE ?) to extract a tree view containing which shape is contained by another one.
Could anyone give some pointers to examples extracting those informations in step file using OCAF or XDE.
I have a difficulty to understand the official document because it has a lack of examples.
EDIT:
By using the Mayo project:
You can use the XdeDocumentItem::XdeDocumentItem(...) constructor and recursively creating the nodes.
XdeDocumentItem::XdeDocumentItem(const Handle_TDocStd_Document &doc)
: m_cafDoc(doc),
m_shapeTool(XCAFDoc_DocumentTool::ShapeTool(doc->Main())),
m_colorTool(XCAFDoc_DocumentTool::ColorTool(doc->Main())){
this->rebuildAssemblyTree();}
The method rebuildAssemblyTree is like that:
for (const TDF_Label& rootLabel : this->topLevelFreeShapes())
this->deepBuildAssemblyTree(0, rootLabel);
You may use class XCAFPrs_DocumentExplorer for stack-alike traverse within OCCT 7.4.0+, and the following code snippet (based on XDisplay Draw Harness command) for traverse with recursive function calls:
//! Handle document root shapes.
int traverseDocument (const Handle(TDocStd_Document)& theDoc)
{
TDF_LabelSequence aLabels;
XCAFDoc_DocumentTool::ShapeTool (theDoc->Main())->GetFreeShapes (aLabels);
for (TDF_LabelSequence::Iterator aLabIter (myLabels); aLabIter.More(); aLabIter.Next())
{
const TDF_Label& aLabel = aLabIter.Value();
if (traverseLabel (aLabel, "", TopLoc_Location()) == 1)
{
return 1;
}
}
return 0;
}
//! Handle single label.
int traverseLabel (const TDF_Label& theLabel,
const TCollection_AsciiString& theNamePrefix,
const TopLoc_Location& theLoc)
{
TCollection_AsciiString aName;
{
Handle(TDataStd_Name) aNodeName;
if (theLabel.FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
aName = aNodeName->Get(); // instance name
}
if (aName.IsEmpty())
{
TDF_Label aRefLabel;
if (XCAFDoc_ShapeTool::GetReferredShape (theLabel, aRefLabel)
&& aRefLabel.FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
aName = aNodeName->Get(); // product name
}
}
}
aName = theNamePrefix + aName;
TDF_Label aRefLabel = theLabel;
XCAFDoc_ShapeTool::GetReferredShape (theLabel, aRefLabel);
if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
{
aName += "/";
const TopLoc_Location aLoc = theLoc * XCAFDoc_ShapeTool::GetLocation (theLabel);
for (TDF_ChildIterator aChildIter (aRefLabel); aChildIter.More(); aChildIter.Next())
{
if (traverseLabel (aChildIter.Value(), aName, aLoc) == 1)
{
return 1;
}
}
return 0;
}
std::cout << aName << " ";
return 0;
}
My OpenGL ES application isn't working. I'm using SDL for windowing management, and it holds the context. After looking around, I noticed that the vertex shader and the fragment shader showed up as 0 on the debugger. Even the program was 0. Could this be a reason? I followed my shader compiling and linking code to a template that was previously made.
If it is, what is wrong? Here is the code:
GLuint ShaderHelper::compileShader(GLenum type, std::string fileName) {
std::string fileContents;
std::ifstream fin;
std::string path;
// Getting the necessary path...
// These are abstractions for getting file contents
// from the main bundle.
if (type == GL_VERTEX_SHADER) {
FileOpener opener;
path = opener.retriveFileFromBundle(fileName, "vsh");
} else if (type == GL_FRAGMENT_SHADER) {
FileOpener opener;
path = opener.retriveFileFromBundle(fileName, "fsh");
} else {
std::cout << "ERROR: Invalid shader type at filename " << fileName << std::endl;
exit(1);
}
fin.open(path);
if (!fin.is_open()) {
std::cout << "ERROR: Failed to open file " << fileName << std::endl;
exit(1);
}
// Retrieving the string from the file...
while (!fin.eof()) {
char CLine[255];
fin.getline(CLine, 255);
std::string line = CLine;
fileContents = fileContents + line;
fileContents = fileContents + " \n";
}
fin.close();
// I'm creating these variables because a pointer is needed for
// glShaderSource
GLuint shaderHandle = glCreateShader(type);
const GLint shaderStringLength = (GLint)fileContents.size();
const GLchar *shaderCString = fileContents.c_str();
glShaderSource(shaderHandle, 1, &shaderCString, &shaderStringLength);
glCompileShader(shaderHandle);
return shaderHandle;
}
void ShaderHelper::linkProgram(std::vector<GLuint *> shaderArray) {
program = glCreateProgram();
for (int i = 0; i < shaderArray.size(); i++) {
glAttachShader(program, *shaderArray[i]);
}
glLinkProgram(program);
}
void ShaderHelper::addUniform(uniform_t uniform) {
std::string name = uniform.name;
uniforms[name] = uniform;
// With that step done, we need to assign the location...
uniforms[name].location = glGetUniformLocation(program, uniforms[name].name.c_str());
}
EDIT: After suggestions, I ran my code through glError(). I fixed an error, but I still got a blank screen. I'm no longer getting 0 as my shader values. I set glClearColor to a white image, and it's just appearing pure white. I adjusted numbers in the MV matrix and projection matrix, but there's still nothing at all. I disabled face culling, but still nothing. Also, shaders are compiling and linking fine. So now what?
The dreaded blank screen can be caused by a variety of problems:
Your context is not created correctly or you're not presenting your scene properly. Does changing your clear color to something else than black show anything?
Your transformation matrix is wrong. How are you setting up the position of the "camera"? Are you using something like GLM to set up a matrix? If so, have a look at glm::perspective() and glm:::lookAt(). Make sure you're passing the matrix to the shader and that you're using it to set gl_Position in your vertex shader.
The geometry you're trying to display is facing away from the viewer. Try glDisable(GL_CULL_FACE). If it works, reverse the order of your vertices.
An OpenGL call is failing somewhere. Make sure you check glGetError() after every call. I usually have something like the following:
struct gl_checker
{
~gl_checker()
{
const auto e = glGetError();
assert(e == GL_NO_ERROR);
}
};
template <class F>
inline auto gl_call(F f) -> decltype(f())
{
gl_checker gc;
return f();
}
which can be used like this:
gl_call([]{ glDisable(GL_CULL_FACE); });
Your shaders fail to compile or link. Have a look at glGetShaderiv() with GL_COMPILE_STATUS and glGetProgramiv() with GL_LINK_STATUS. If they report an error, have a look at glGetShaderInfoLog() and glGetProgramInfoLog().
As for the partial code you provided, I see nothing strictly wrong with it. Providing the shaders and a smaller, complete program might help with finding the problem.
I am trying to read glyph outline for a character using FreeType lib.I load font from a standard .ttf file.Till now I was using outline tags to convert outline to path elements like segments and bezier curves.Then I found FT_Outline_Decompose which is a part of the lib.But when I am using it,the decomposed data values are huge.Every point on the path as a value of ~ 859722XXX .So even the down-scaling with factor of 64 as it's suggested by examples doesn't help to get pixel size values.
My code goes like this:
const char* fontFile ="fonts/Verdana.ttf";
std::string chars("Uta \n");
char charcode = chars[0];
FT_Library defLibHandle;
FT_Error err = FT_Init_FreeType(&defLibHandle);
if(err){
printf(ft_errors[err].err_msg);
throw;
}
FT_Face faceHandle;
err = FT_New_Face(defLibHandle,fontFile,0,&faceHandle);
if(err){
printf(ft_errors[err].err_msg);
throw;
}
FT_Glyph glyph;
// load glyph
err = FT_Load_Char(faceHandle,
charcode,
FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE);
if (err) {
std::cout << "FT_Load_Glyph: error\n";
}
//FT_Get_Glyph(faceHandle->glyph, &glyph);
FT_Outline outline = faceHandle->glyph->outline;
if (faceHandle->glyph->format != ft_glyph_format_outline) {
std::cout << "not an outline font\n";
}
FT_Outline_Funcs funcs;
funcs.move_to = (FT_Outline_MoveTo_Func)&moveTo;
funcs.line_to = (FT_Outline_LineTo_Func)&lineTo;
funcs.conic_to = (FT_Outline_ConicTo_Func)&conicTo;
funcs.cubic_to = (FT_Outline_CubicTo_Func)&cubicTo;
// trace outline of the glyph
err = FT_Outline_Decompose(&outline,
&funcs, nullptr);
if (err) {
std::cout <<ft_errors[err].err_msg ;
}
Now, in the callbacks like moveTo() I attempt to resize:
int moveTo(FT_Vector* to, void* fp) {
pathRef->moveTo(ftVecToFloat(to)); ///
// ftVecToFloat is "float(f) / 64.0f" ///
return 0;
}
But the initial FT_Vector value is so huge that the division by 64.0 still doesn't matters.
set
funcs.shift = 0;
funcs.delta = 0;
will work