this question is a continuing of Error on Constrained Delaunay Triangulation and Gabriel Triangulations
Trying to write a minimal example for that problem I planned insert the triangulation
in a file (std::ofstream) using the << operator of CDT without calling the CGAL::make_conforming_Delaunay_2(cdt); or CGAL::make_conforming_Gabriel_2(cdt),
knowing that until this point everything occured OK.
The triangulation was created without problems and before the exit of the aplication I saved the triangulation in a file using the << operator of CDT. The file was saved without error.
When I tried to read the file using the >> operator of CDT an exception was raised (inside the >> operator). The text of exception is:
CGAL ERROR: assertion violation!\nExpr: s == LEFT_TURN\nFile: C:\\dev\\CGAL-5.3.1\\include\\CGAL\\Triangulation_2.h\nLine: 919
The code I wrote:
int main()
{
CDT cdt;
std::ifstream ArqSuperficie("trian.dtr"); This file was created with << operator of CDT
if (ArqSuperficie.good() == false)
{
return 1;
}
try()
{
ArqSuperficie >> cdt;
}
catch(std::exception& e)
{
std::cerr << "ERROR: exception " << e.what() << std::endl;
}
return 0;
}
Why CDT cannot read a file created by itself, of a triangulation that was created by itself without errors?
Based on the message of the exception I canĀ“t have a clue of what is happening...
Thank you
Related
Problem description
I read the mesh from the file "blank.off" and load it into the a surface_mesh variable blank. One file named "hepoints49.txt" stores point clouds. I use function CGAL::advancing_front_surface_reconstruction() to convert this point cloud to surface_mesh sv, and then use function corefine_and_compute_difference(blank,sv,res) to perform the Boolean subtraction between blank and sv.But the program throws an exception and terminates. The following is displayed on the terminal:
Using context 4 . 3 GL
load sv...
Using context 4 . 3 GL
start difference...
CGAL error: precondition violation!
Expression : CGAL::is_valid_polygon_mesh(tm)
File : D:\dev\vcpkg\installed\x64-windows\include\CGAL/Polygon_mesh_processing/orientation.h
Line : 190
Could you please help me solve this problem?
code
#include<iostream>
#include<io.h>
#include<fstream>
#include<algorithm>
#include<array>
#include<CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include<CGAL/Advancing_front_surface_reconstruction.h>
#include<CGAL/Surface_mesh.h>
#include<CGAL/disable_warnings.h>
#include<CGAL/draw_surface_mesh.h>
#include<ctime>
#include<string>
#include<CGAL/polygon_mesh_processing/corefinement.h>
#include<CGAL/polygon_mesh_processing/remesh.h>
#include<CGAL/boost/graph/selection.h>
#include<CGAL/polygon_mesh_processing/repair_self_intersections.h>
using std::cin;
using std::cout;
using std::endl;
using std::string;
namespace PMP = CGAL::Polygon_mesh_processing;
typedef std::array<std::size_t, 3> Facet;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Mesh;
struct Construct {
Mesh& mesh;
template <typename PointIterator>
Construct(Mesh& mesh, PointIterator b, PointIterator e):mesh(mesh) {
for (; b != e; ++b) {
boost::graph_traits<Mesh>::vertex_descriptor v;
v = add_vertex(mesh);
mesh.point(v) = *b;
}
}
Construct& operator=(const Facet f) {
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::vertices_size_type size_type;
mesh.add_face(vertex_descriptor(static_cast<size_type>(f[0])),
vertex_descriptor(static_cast<size_type>(f[1])),
vertex_descriptor(static_cast<size_type>(f[2])));
return *this;
}
Construct& operator*() { return *this; }
Construct& operator++() { return *this; }
Construct& operator++(int) { return *this; }
};
int main() {
//load blank
Mesh blank, sv,res;
std::ifstream fin("blank.off");
fin>>blank;
fin.close();
CGAL::draw(blank);
//load sv
string filename = "hepoints49.txt" ;
std::cout << "load sv..."<< std::endl;
fin.open(filename);
std::vector<Point_3> points;
std::vector<Facet> facets;
std::copy(std::istream_iterator<Point_3>(fin),
std::istream_iterator<Point_3>(),
std::back_inserter(points));//load points
fin.close();
Construct construct(sv, points.begin(), points.end());
CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), construct);//convert sv to surface_mesh
CGAL::draw(sv);
std::cout << "start difference..." << std::endl;
bool valid_difference = PMP::corefine_and_compute_difference(blank,sv,res);
if (valid_difference) {
std::cout << "difference was successfully computed. " << std::endl;
CGAL::draw(res);
}
else {
std::cout << "difference could not be completed. Skip. " << endl << endl;
}
//CGAL::draw(res);
return 0;
}
Runtime environment
CGAL version: 5.3
IDE: VS2017
Solution Configuration: Debug x64
I tried to run this program in Release mode, of course there is no exception thrown. But the result I got turned out to be the opposite of what I want.
Files
Files that appearing in the code are provided below:
https://github.com/wenzaifou/for-stack-overflow-question3.git
Github link is provided because the file is relatively large.
The way the mesh is constructed from advancing front output does not filter out isolated vertices, which causes the exception to be raised. Adding a call to CGAL::Polygon_mesh_processing::remove_isolated_vertices(sv) will solve the problem.
Then you might encounter the issue that your meshes are not outward oriented (meaning then represent an infinite portion of space). Adding the following calls will solve the problem:
if (!CGAL::Polygon_mesh_processing::is_outward_oriented(blank))
CGAL::Polygon_mesh_processing::reverse_face_orientations(blank);
if (!CGAL::Polygon_mesh_processing::is_outward_oriented(sv))
CGAL::Polygon_mesh_processing::reverse_face_orientations(sv);
Doc refs here and there.
Although I don't know how to write C++ I am trying to use CGAL for trying to derive building shapes from LiDAR point clouds using Point Set Shape Detection. Using the examples I can read points and normals from a file, whereupon CGAL detects shapes. The program is set to detect only planar shapes.
I would like to save the planar shapes to a file, so that I can use them in other software. But I was unable to find examples of how that can be achieved. The test program I use is based on the efficient_RANSAC_parameters.cpp code. It has a part when it iterates through all detected shapes. Could it be possible to add something there that will write the planar shapes to a file? I see the OFF format is a popular and simple way (in CGAL) to save polygons to a file, so that could be a good candidate file format.
A colleague who does know how to write C++ has helped me with this problem. He came up with the following:
while (it != shapes.end()) {
if (Plane* plane = dynamic_cast<Plane*>(it->get()))
{
std::cout << "PLANE_" << count++ << "[" << std::endl;
const std::vector<size_t> indices = it->get()->indices_of_assigned_points();
std::vector<size_t>::const_iterator iti = indices.begin();
while (iti != indices.end()) {
// Retrieves point
Point_with_normal pw = *(points.begin() + (*iti));
Kernel::Point_3 p = pw.first;
std::cout << "POINT[" << p.x() << "," << p.y() << "," << p.z() << "]" << std::endl;
// Proceeds with next point.
iti++;
}
std::cout << "]" << std::endl;
}
// Proceeds with next detected shape.
it++;
}
This block can replace loop in the efficient_RANSAC_parameters.cpp example. The output looks like this:
PLANE_0[
POINT[34.96,584.49,0.47]
POINT[34.97,585.24,0.54]
POINT[34.88,584.51,0.49]
POINT[34.98,584.75,0.49]
]
That gives me something to work with. In my case, I use sed to transform this output to SQL insert queries that allow me to transfer the data to a relational database for further processing.
In the example in the user manual you can see that once you have a plane shape object
if(Plane* plane = dynamic_cast<Plane*>(it->get())){..} you can obtain from the plane shape object a CGAL::Plane_3, from which you can obtain a point and a normal, or the coefficients of the plane.
For debuging prurpose I wouls like to print a sql query I am executing.
Here is my code:
QSqlQuery query;
query.prepare("INSERT INTO GeoAndEnergies VALUES(:smi,:chismi,:index,:rank,:comp,:met,:ba,:nha, :na, :gr, :gconv, :scfconv, :ener,:chemf,:prog,:ver,:cha,:mult,:sol,:geo, :freq, :enth, :free_e, :wei)");;
query.bindValue(":smi",QVariant(SMILES));
query.bindValue(":chismi",QVariant(ChiralSMILES));
query.bindValue(":index",QVariant(IndexCS));
query.bindValue(":rank",QVariant(Confrank));
query.bindValue(":comp",QVariant(Comptype));
query.bindValue(":met",QVariant(Method));
query.bindValue(":ba",QVariant(BASE));
query.bindValue(":nha",QVariant(NheavyAtom));
query.bindValue(":na",QVariant(NAtoms));
query.bindValue(":gr",QVariant(Grid));
query.bindValue(":gconv",QVariant(GeoConvergence));
query.bindValue(":scfconv",QVariant(SCFConvergence));
query.bindValue(":ener",QVariant(Energy));
query.bindValue(":chemf",QVariant(ChemicalFormula));
query.bindValue(":prog",QVariant(SOFTWARE));
query.bindValue(":ver",QVariant(VERSION));
query.bindValue(":cha",QVariant(Charge));
query.bindValue(":mult",QVariant(Multiplicity));
query.bindValue(":sol",QVariant(SOLVANT));
query.bindValue(":geo",QVariant(Geometry));
query.bindValue(":freq",QVariant(freq));
query.bindValue(":enth",QVariant(enthalpy));
query.bindValue(":free_e",QVariant(free_enthalpy));
query.bindValue(":wei",QVariant(weight));
if (!query.exec()){
std::cout << "Une erreur s'est produite. :(" << std::endl << q2c(query.lastError().text()) << std::endl;
}
return;
Thanks for tips.
query.executedQuery() will return the text of the last query that was successfully executed, with placeholder values replaced with concrete values. Hopefully, it'll also work if there was an error due to bad values, etc.
Note also that the explicit QVariant constructions are never necessary. For types that are handled by QVariant, the conversion will be done automatically. For custom types, there's no QVariant constructor available and the code won't compile anyway. You'd need to use QVariant::fromValue(xyz), where xyz has a custom type that has been Q_DECL_METATYPE'd in the header where the type is declared.
Your code could be rewritten as follows:
QSqlQuery query;
query.prepare("INSERT INTO GeoAndEnergies VALUES(:smi,:chismi,:index,:rank,:comp,:met,:ba,:nha, :na, :gr, :gconv, :scfconv,"
":ener,:chemf,:prog,:ver,:cha,:mult,:sol,:geo, :freq, :enth, :free_e, :wei)");
query.bindValue(":smi", SMILES);
query.bindValue(":chismi", ChiralSMILES);
query.bindValue(":index", IndexCS);
query.bindValue(":rank", Confrank);
query.bindValue(":comp", Comptype);
query.bindValue(":met", Method);
query.bindValue(":ba", BASE);
query.bindValue(":nha", NheavyAtom);
query.bindValue(":na", NAtoms);
query.bindValue(":gr", Grid);
query.bindValue(":gconv", GeoConvergence);
query.bindValue(":scfconv", SCFConvergence);
query.bindValue(":ener", Energy);
query.bindValue(":chemf", ChemicalFormula);
query.bindValue(":prog", SOFTWARE);
query.bindValue(":ver", VERSION);
query.bindValue(":cha", Charge);
query.bindValue(":mult", Multiplicity);
query.bindValue(":sol", SOLVANT);
query.bindValue(":geo", Geometry);
query.bindValue(":freq", freq);
query.bindValue(":enth", enthalpy);
query.bindValue(":free_e", free_enthalpy);
query.bindValue(":wei", weight);
if (!query.exec()) {
qWarning() << "The query has failed:" << query.executedQuery();
}
I wrote a shortest path code in Graphchi and I wanted to print the output of that in a file. I was trying to use the template shown in the examples but I get error if I use the sameway of writing to a file as in other examples.
I have got stuck here. As the output I just want to print (vertex id,its minimum distance from source).
How can i do that.
Here is example how you can output values of all vertices to the console. It is easy to modify it to write the output to a file. Note that if you can handle binary files, GraphChi already has the vertex values in a file: .B.vout, where is sizeof(VertexDataType).
1) You need to define a callback-function, which will take vertex id and value as parameter
class OutputVertexCallback : public VCallback<VertexDataType> {
public:
virtual void callback(vid_t vertex_id, VertexDataType &value) {
std::cout << vertex_id << "=" << value << std::endl;
}
};
2) Then you need to call foreach_vertices() as follows to get the output:
OutputVertexCallback callback;
foreach_vertices<VertexDataType>(filename, 0, engine.num_vertices(), callback);
I'm using Visual C++ 2005 and would like to know the simplest way to connect to a MS SQL Server and execute a query.
I'm looking for something as simple as ADO.NET's SqlCommand class with it's ExecuteNonQuery(), ExecuteScalar() and ExecuteReader().
Sigh offered an answer using CDatabase and ODBC.
Can anybody demonstrate how it would be done using ATL consumer templates for OleDb?
Also what about returning a scalar value from the query?
With MFC use CDatabase and ExecuteSQL if going via a ODBC connection.
CDatabase db(ODBCConnectionString);
db.Open();
db.ExecuteSQL(blah);
db.Close();
You should be able to use OTL for this. It's pretty much:
#define OTL_ODBC_MSSQL_2008 // Compile OTL 4/ODBC, MS SQL 2008
//#define OTL_ODBC // Compile OTL 4/ODBC. Uncomment this when used with MS SQL 7.0/ 2000
#include <otlv4.h> // include the OTL 4.0 header file
#include <stdio>
int main()
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try
{
int myint;
db.rlogon("scott/tiger#mssql2008"); // connect to the database
otl_stream select(10, "select someint from test_tab", db);
while (!select.eof())
{
select >> myint;
std::cout<<"myint = " << myint << std::endl;
}
}
catch(otl_exception& p)
{
std::cerr << p.code << std::endl; // print out error code
std::cerr << p.sqlstate << std::endl; // print out error SQLSTATE
std::cerr << p.msg << std::endl; // print out error message
std::cerr << p.stm_text << std::endl; // print out SQL that caused the error
std::cerr << p.var_info << std::endl; // print out the variable that caused the error
}
db.logoff(); // disconnect from the database
return 0;
}
The nice thing about OTL, IMO, is that it's very fast, portable (I've used it on numerous platforms), and connects to a great many different databases.
I used this recently:
#include <ole2.h>
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#include <oledb.h>
void CMyDlg::OnBnClickedButton1()
{
if ( FAILED(::CoInitialize(NULL)) )
return;
_RecordsetPtr pRs = NULL;
//use your connection string here
_bstr_t strCnn(_T("Provider=SQLNCLI;Server=.\\SQLExpress;AttachDBFilename=C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\db\\db.mdf;Database=mydb;Trusted_Connection=Yes;MARS Connection=true"));
_bstr_t a_Select(_T("select * from Table"));
try {
pRs.CreateInstance(__uuidof(Recordset));
pRs->Open(a_Select.AllocSysString(), strCnn.AllocSysString(), adOpenStatic, adLockReadOnly, adCmdText);
//obtain entire restult as comma separated text:
CString text((LPCWSTR)pRs->GetString(adClipString, -1, _T(","), _T(""), _T("NULL")));
//iterate thru recordset:
long count = pRs->GetRecordCount();
COleVariant var;
CString strColumn1;
CString column1(_T("column1_name"));
for(int i = 1; i <= count; i++)
{
var = pRs->GetFields()->GetItem(column1.AllocSysString())->GetValue();
strColumn1 = (LPCTSTR)_bstr_t(var);
}
}
catch(_com_error& e) {
CString err((LPCTSTR)(e.Description()));
MessageBox(err, _T("error"), MB_OK);
_asm nop; //
}
// Clean up objects before exit.
if (pRs)
if (pRs->State == adStateOpen)
pRs->Close();
::CoUninitialize();
}
Try the Microsoft Enterprise Library. A version should be available here for C++. The SQlHelper class impliments the methods you are looking for from the old ADO days. If you can get your hands on version 2 you can even use the same syntax.