Taking a look at a constraint validator for heekscad

I’ve been mulling this over a bit.
I want to be able to check the constraints on the fly as see If I can pinpoint precisely the point at which they get hose up.
I’m thinking that I need to study the saveXml routine and see it makes sense.
So I guess I need to explore what ever seems to be happening with constraints.

void HeeksCADapp::SaveXMLFile(const std::list& objects, const wxChar *filepath, bool for_clipboard)
{
// write an xml file
TiXmlDocument doc;
const char *l_pszVersion = “1.0”;
const char *l_pszEncoding = “UTF-8”;
const char *l_pszStandalone = “”;

TiXmlDeclaration* decl = new TiXmlDeclaration( l_pszVersion, l_pszEncoding, l_pszStandalone);
doc.LinkEndChild( decl );

TiXmlNode* root = &doc;
if(!for_clipboard)
{
root = new TiXmlElement( “HeeksCAD_Document” );
doc.LinkEndChild( root );
}

// loop through all the objects writing them
CShape::m_solids_found = false;
Constraint::BeginSave();
for(std::list::const_iterator It = objects.begin(); It != objects.end(); It++)
{
HeeksObj* object = *It;
object->WriteXML(root);
}

// write the constraints to the root-if check box is selected
if (m_save_constraints){
Constraint::EndSave(root);
}

// write a step file for all the solids
if(CShape::m_solids_found){
wxStandardPaths sp;
sp.GetTempDir();
wxFileName temp_file( sp.GetTempDir().c_str(), _T(“temp_HeeksCAD_STEP_file.step”) );
std::map index_map;
CShape::ExportSolidsFile(objects, temp_file.GetFullPath(), &index_map);

TiXmlElement *step_file_element = new TiXmlElement( “STEP_file” );
root->LinkEndChild( step_file_element );

// write the index map as a child of step_file
{
TiXmlElement *index_map_element = new TiXmlElement( “index_map” );
step_file_element->LinkEndChild( index_map_element );
for(std::map::iterator It = index_map.begin(); It != index_map.end(); It++)
{
TiXmlElement *index_pair_element = new TiXmlElement( “index_pair” );
index_map_element->LinkEndChild( index_pair_element );
int index = It->first;
CShapeData& shape_data = It->second;
index_pair_element->SetAttribute(“index”, index);
index_pair_element->SetAttribute(“id”, shape_data.m_id);
index_pair_element->SetAttribute(“title”, Ttc(shape_data.m_title));
index_pair_element->SetAttribute(“vis”, shape_data.m_visible ? 1:0);
if(shape_data.m_solid_type != SOLID_TYPE_UNKNOWN)index_pair_element->SetAttribute(“solid_type”, shape_data.m_solid_type);
// get the CShapeData attributes
for(TiXmlAttribute* a = shape_data.m_xml_element.FirstAttribute(); a; a = a->Next())
{
index_pair_element->SetAttribute(a->Name(), a->Value());
}

// write the face ids
for(std::list::iterator It = shape_data.m_face_ids.begin(); It != shape_data.m_face_ids.end(); It++)
{
int id = *It;
TiXmlElement *face_id_element = new TiXmlElement( “face” );
index_pair_element->LinkEndChild( face_id_element );
face_id_element->SetAttribute(“id”, id);
}

// write the edge ids
for(std::list::iterator It = shape_data.m_edge_ids.begin(); It != shape_data.m_edge_ids.end(); It++)
{
int id = *It;
TiXmlElement *edge_id_element = new TiXmlElement( “edge” );
index_pair_element->LinkEndChild( edge_id_element );
edge_id_element->SetAttribute(“id”, id);
}
}
}

// write the step file as a string attribute of step_file
#ifdef __WXMSW__
ifstream ifs(temp_file.GetFullPath());
#else
ifstream ifs(Ttc(temp_file.GetFullPath().c_str()));
#endif
if(!(!ifs)){
std::string fstr;
char str[1024];
while(!(ifs.eof())){
ifs.getline(str, 1022);
strcat(str, “\n”);
fstr.append(str);
if(!ifs)break;
}

TiXmlElement *file_text_element = new TiXmlElement( “file_text” );
step_file_element->LinkEndChild( file_text_element );
TiXmlText *text = new TiXmlText(fstr.c_str());
text->SetCDATA(true);
file_text_element->LinkEndChild( text );
}
}

doc.SaveFile( Ttc(filepath) );
}

The beginsave this just clears stuff off.
The endsave looks promising:

void Constraint::EndSave(TiXmlNode *root)
{
std::list<Constraint*>::iterator it;
for(it = obj_to_save.begin(); it != obj_to_save.end(); it++)
{
Constraint *c = *it;
TiXmlElement * element;
element = new TiXmlElement( “Constraint” );
root->LinkEndChild( element );
element->SetAttribute(“type”, ConstraintTypes[c->m_type].c_str());
element->SetAttribute(“angle”, AbsoluteAngle[c->m_angle].c_str());
element->SetDoubleAttribute(“length”, c->m_length);
element->SetAttribute(“obj1_id”,c->m_obj1->m_id);
element->SetAttribute(“obj1_type”,c->m_obj1->GetIDGroupType());
if(c->m_obj2)
{
element->SetAttribute(“obj2_id”,c->m_obj2->m_id);
element->SetAttribute(“obj2_type”,c->m_obj2->GetIDGroupType());
}
c->WriteBaseXML(element);
}
}

I think I just need to create separate member function copy this over and strip out the xml stuff and compare it to the actual list and see it it jives. Could it be this easy??
In the endsave function there’s a few things going on that I need to thing about.
obj_to_save is a a list which gets cleared by begin_save and added to by WriteBaseXML
Ok… Time to freshen up on stl::lists a bit.  http://www.sgi.com/tech/stl/List.html

At first glance this looks really easy… But now the question I’m asking myself is how does:

static std::list<Constraint*> obj_to_save;

get populated.  Ok… I know it gets populated by WriteBaseXML(element)

void Constraint::WriteXML(TiXmlNode *root)
{
if(obj_to_save_find.find(this)!=obj_to_save_find.end())
return;

obj_to_save.push_back(this);
obj_to_save_find.insert(this);
}

So… Apparently, obj_to_save is all coming from XML stuff. This is far too down stream in the process for what I’m looking to do.
(I’m still confused by how this endsave thing works… I need to need to go a little further upstream in this.
Ok… I think what going on with the WriteXML stuff is that it’s not actually writing to file but more like assembling the pieces. I think that might have been confusing me.
Although, I think it looks like constraints get written out/assembled after everything else is done.  (Which makes sense when you see the actual file).

Looking at everything the thing that’s confusing me and I suspect might be a bug (but I need study this a little further):
if(obj_to_save_find.find(this)!=obj_to_save_find.end())

obj_to_save_find is declared as:
std::set<Constraint*> obj_to_save_find;

Information on set appears here:

http://www.sgi.com/tech/stl/set.html
(Note to self..  I think things would be much clearer if obj_to_save,  obj_to_save_find where renamed to constraint_obj_to_save,  constraint_obj_to_save_find)

Limiting this from the constraints perspective and looking at the following routines I think this is what’s going on.

void HeeksCADapp::SaveXMLFile(const std::list& objects, const wxChar *filepath, bool for_clipboard) basically clears out a set and list of Constraint pointers from the very beginning.

SaveXMLFile iterates through “objects” which I don’t understand where that was declared or populated at the moment…… Arrrrgh.
So… I think that SaveXML iterates through the object list and writes out XML until it hit a constraint.
I believe that the intent is that constraints are written out at the end, if the constraint is on the set list already ignore it, otherwise add it to set and list and deal with it at endsave.

Before I persue this theory… I need to understand where objects gets populated in the initial SaveXMLfile and I’m out of time today…..

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *