Author Topic: Project-Auditing dwgs to a CAD Standard  (Read 31735 times)

0 Members and 1 Guest are viewing this topic.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #60 on: July 23, 2008, 11:03:09 AM »
I guess if we wanted to report it, we can do it the way audit does

I would suggest the same way as the CAD Standards Checker does. This way, you can email the report to the insultant and they know what to fix. If you do it like audit, it's not very friendly.
What would that look like Glenn?  I don't have a dws file around

SaveAs any drawing to DWS and you magically have a standards file. Then go to Batch Standards Checker, select drawings, tell it to use the DWS file and off you go.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #61 on: July 23, 2008, 11:11:23 AM »
I think I have it worked out in my head how to check the fonts and layers, I'm going to try and code that up today.

Duh,

I'm sorry, but I'm at a loss as to how you're going to accomplish this, when we haven't even decided what the XML config file looks like, let alone it's contents. This application config file would tell the app what to check, possible DWS files to use etc. etc...whatever we want.

Going off and doing the layers and fonts, whilst good for practice, is a bit premature I think or do you have something else in mind?

Cheers,
Glenn.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Project-Auditing dwgs to a CAD Standard
« Reply #62 on: July 23, 2008, 11:25:00 AM »
I guess if we wanted to report it, we can do it the way audit does

I would suggest the same way as the CAD Standards Checker does. This way, you can email the report to the insultant and they know what to fix. If you do it like audit, it's not very friendly.
What would that look like Glenn?  I don't have a dws file around

SaveAs any drawing to DWS and you magically have a standards file. Then go to Batch Standards Checker, select drawings, tell it to use the DWS file and off you go.
I'm not sure how you could relate what is wrong, as far as drawn objects, like they do in the DWS checker.  I guess if the report was going to be in some text file, then it could be formatted like that.  But my question would still be how does one know which items are not in compliance?  Since the handle doesn't change, that is why I was reporting that.  Do you have an idea of what the output file is going to be?  Or how it is supposed to look?  I don't think that would be too hard to change the code once those items have been confirmed.

How else would one report which items did not meet standards?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Project-Auditing dwgs to a CAD Standard
« Reply #63 on: July 23, 2008, 12:23:48 PM »
I'm sorry, but I'm at a loss as to how you're going to accomplish this, when we haven't even decided what the XML config file looks like, let alone it's contents.
I was going under the assumption that we would pull the valid layers, text styles, dim settings, and the other 4th item I cant seem to remember from the dws file.  I haven't figured out what I think needs to go into the XML file yet, as that seems like a huge undertaking, that could involve lots of info, which as you said, hasn't been thought up yet.
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #64 on: July 23, 2008, 01:59:13 PM »
Just to be clear, I'm referring to the XML file for app configuration (what DWS's to grab and from where for example), not the output file...

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Project-Auditing dwgs to a CAD Standard
« Reply #65 on: July 23, 2008, 03:03:02 PM »
Well I'm glad you said that, because I was going the wrong direction.  Do we have a method of editing the XML config file from within our app?  I'm thinking that would be a "settings" button on main page that opens a form where we can browse to the DWS file, pick paths, etc.  All of that data would then be stored in XML, possibly in the same folder as our app, or would we create a subfolder for the app?
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Project-Auditing dwgs to a CAD Standard
« Reply #66 on: July 23, 2008, 03:11:16 PM »
In the simplest of terms, is this kinda what we are talking about creating as the config file?  I know there is a lot missing, Im just trying to get my mind headed in the right direction
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>
<CadQcQaConfig>
<OutputFolder>
  <Folder>Path to Output Folder for results </Folder>
</OutputFolder>
<Source>
  <DWSFile>path to DWS File</DWSFile>
</Source>
</CadQcQaConfig>code]
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #67 on: July 23, 2008, 03:35:10 PM »
Exactly Duh, with the exception that you wouldn't store in a sub folder...all in the same folder as you suggest.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #68 on: July 23, 2008, 04:52:14 PM »
In the simplest of terms, is this kinda what we are talking about creating as the config file?  I know there is a lot missing, Im just trying to get my mind headed in the right direction
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>
<CadQcQaConfig>
<OutputFolder>
  <Folder>Path to Output Folder for results </Folder>
</OutputFolder>
<Source>
  <DWSFile>path to DWS File</DWSFile>
</Source>
</CadQcQaConfig>code]

Yep - that's the idea...now start having a good long think about it. Once you do, you'll realise there's a bit more to this than meets the eye, but it will definitely be worth it in the end me thinks.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #69 on: July 25, 2008, 10:37:00 AM »
I've been playing  :-)

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #70 on: July 25, 2008, 10:37:39 AM »
More later...I hope :)

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #71 on: July 29, 2008, 03:40:50 PM »
Well...after a couple of days looking and transposing an old ADN sample (VB and for acad 2004) and the CircleSample ATL ObjectARX sample, I've managed to create a plugin to check circles colours.

There were a lot more hoops to jump through than I first envisaged, however, having said this, I think 'it has legs' and will be quite useful. I will post more when I sort out some other questions that have come to mind from this exercise.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #72 on: August 01, 2008, 08:53:51 AM »
Ask and ye shall receive.

Thanks to Kean for posting this - I'm sure it will benefit the discussions both here and there.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #73 on: August 01, 2008, 08:59:38 AM »
Here is my effort cobbled together from the ADN doc Kean mentions and the ARX sample CircleStandard:

Code: [Select]
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace tcgsAcStdCircles
{
[ProgId("tcgsAcStdCircles.AcStdCirclesTest")]
[ClassInterface(ClassInterfaceType.None)]
[Guid("B26515F6-D667-467d-9F9F-E2A0B3ADD594")]
[ComVisible(true)]
public class AcStdCirclesTest : AcStMgr.IAcStPlugin2
{
#region Private field(s)

private string _name;
private string _author;
private string _description;
private string _href;
private string _version;
private string _propName;

private AcStMgr.AcStManager _manager;
private AcStdCirclesTest _plugin;
private AcStMgr.AcStError _error;

private AXDBLib.AcadDatabase _checkDb;
private AXDBLib.AcadDatabase _dwsDb;

private List<CircleCache> _circleCache;
private List<int> _idsToCheck;

private bool _useDb;

private int _currentIndex;
private int _recommendedFixIndex;
private int _fixCount;

#endregion

#region Default ctor

public AcStdCirclesTest()
{
_name = "Circles";
_author = "TCGSoftware";
_description = "Checks that properties of circles in a drawing match those in an associated standards file.";
_href = "www.tcgsoftware.com";
_version = "1.0";

_idsToCheck = new List<int>();
_circleCache = new List<CircleCache>();

_useDb = false;
}

#endregion

#region IAcStPlugin2 Members

public string Author
{
get { return _author; }
}

public void CheckSysvar(string syvarName, bool bGetAllFixes, ref bool bPassFail)
{
// Not implemented yet.
}

public void Clear()
{
_name = string.Empty;
_description = string.Empty;
_author = string.Empty;
_href = string.Empty;
_version = string.Empty;

if (_circleCache != null)
{
for (int i = 0; i < _circleCache.Count; i++)
{
if (_circleCache[i].Fix != null)
{
_circleCache[i].Fix.Reset();
_circleCache[i] = null;
}
}
_circleCache = null;
}

_plugin = null;
_manager = null;
if (_error != null)
{
_error.Reset();
_error = null;
}

_checkDb = null;
_dwsDb = null;

_idsToCheck.Clear();
_idsToCheck = null;

}

public string Description
{
get { return _description; }
}

public bool Done()
{
return (_error == null);
}

public void FixError(AcStMgr.AcStError pError, AcStMgr.AcStFix pFix, out string pFailedReason)
{
pFailedReason = "0";
if (pError != null)
{
object fixVal = null;

int badEntId = pError.BadObjectId;
AXDBLib.AcadCircle badEnt = _checkDb.ObjectIdToObject(badEntId) as AXDBLib.AcadCircle;

if (pFix == null)
{
// if the fix object is null, then attempt to get a recommended fix
AcStMgr.AcStFix tmpFix = GetRecommendedFix(pError);
if (tmpFix == null)
{
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResNoRecommendedFix;
}
else
{
// Fix the naughty circle
pFix = tmpFix;
tmpFix = null;
pFix.PropertyValueGet(_propName, ref fixVal);
try
{
badEnt.color = (AXDBLib.ACAD_COLOR)fixVal;
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResFixed;
}
catch
{
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResFixFailed;
}
}
}
else
{
// Fix the naughty circle
pFix.PropertyValueGet(_propName, ref fixVal);
try
{
badEnt.color = (AXDBLib.ACAD_COLOR)fixVal;
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResFixed;
}
catch
{
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResFixFailed;
}
}
}
}

public void GetAllFixes(AcStMgr.AcStError pError, ref object fixArray, ref int recommendedFixIndex)
{
if (pError != null)
{
AcStMgr.IAcStFix[] arr = new AcStMgr.IAcStFix[_circleCache.Count];

// use our fix candidates if we have any
if (_circleCache.Count > 0)
{
for (int i = 0; i < _circleCache.Count; i++)
{
AXDBLib.ACAD_COLOR errorVal = (AXDBLib.ACAD_COLOR)pError.PropertyValueGet("Color");
if (errorVal.CompareTo(_circleCache[i].Colour) != 0)
{
arr[i] = _circleCache[i].Fix;
}
}

fixArray = arr;

GetRecommendedFix(pError);

recommendedFixIndex = _recommendedFixIndex;
}

if (recommendedFixIndex == -1)
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResNoRecommendedFix;
}
}

public AcStMgr.AcStError GetError()
{
return _error;
}

public object GetObjectFilter()
{
string[] filter = { "AcDbCircle" };
return filter;
}

public void GetPropertyDiffs(AcStMgr.AcStError pError, AcStMgr.AcStFix pFix,
ref object pPropNames, ref object pErrorValues, ref object pFixValues, ref object pFixableStatuses)
{
if (pError != null)
{
List<string> propNames = new List<string>();
string propName = string.Empty;

List<string> errorValues = new List<string>();
object errorVal = null;

List<string> fixValues = new List<string>();
object fixVal = null;

List<bool> fixableStatuses = new List<bool>();

for (int i = 0; i < pError.PropertyCount; i++)
{
pError.PropertyGetAt(i, ref propName, ref errorVal);
_propName = propName;

// Retrieve corresponding Fix property value
try
{
pFix.PropertyValueGet(propName, ref fixVal);
if (((AXDBLib.ACAD_COLOR)errorVal).CompareTo((AXDBLib.ACAD_COLOR)fixVal) != 0)
{
propNames.Add(propName);
errorValues.Add(errorVal.ToString());
fixValues.Add(fixVal.ToString());
fixableStatuses.Add(true);
}
}
catch
{
// explicit catch-all here.
}
}

pPropNames = propNames.ToArray();
pErrorValues = errorValues.ToArray();
pFixValues = fixValues.ToArray();
pFixableStatuses = fixableStatuses.ToArray();

_fixCount++;
}
}

public AcStMgr.AcStFix GetRecommendedFix(AcStMgr.AcStError pError)
{
AcStMgr.AcStFix recommendedFix = new AcStMgr.AcStFix();
_recommendedFixIndex = 0;

if (_circleCache.Count == 0)
{
pError.ResultStatus = AcStMgr.AcStResultStatus.acStResNoRecommendedFix;
}
else
{
AXDBLib.AcadCircle circ = (AXDBLib.AcadCircle)_checkDb.ObjectIdToObject(pError.BadObjectId);
double diff = System.Math.Abs(circ.Radius - _circleCache[0].Radius);

for (int i = 0; i < _circleCache.Count; i++)
{
if (diff > Math.Abs(circ.Radius - _circleCache[i].Radius))
{
diff = Math.Abs(circ.Radius - _circleCache[i].Radius);
_recommendedFixIndex = i;
}
}

recommendedFix.Description = "Colour fix";
recommendedFix.StandardFileName = _circleCache[_recommendedFixIndex].StandardFileName;
recommendedFix.FixObjectName = "Color";
if (recommendedFix.PropertyCount == 0)
{
recommendedFix.PropertyValuePut("Color", _circleCache[_recommendedFixIndex].Colour);
}
}

return recommendedFix;
}

public string HRef
{
get { return _href; }
}

public int Icon
{
get { return 1; }
}

public void Initialize(AcStMgr.AcStManager pMgr)
{
_manager = pMgr;
_plugin = this;
}

public string Name
{
get { return _name; }
}

public void Next()
{
_error = null;
bool foundError = false;

if ((_idsToCheck.Count > 0) && (_circleCache.Count > 0))
{
if (_currentIndex < _idsToCheck.Count)
{
_currentIndex++;

while (_currentIndex < _idsToCheck.Count)
{
AXDBLib.AcadCircle circ = _checkDb.ObjectIdToObject(_idsToCheck[_currentIndex]) as AXDBLib.AcadCircle;

// iterate over our list of cached circle props and look for a match
foreach (CircleCache cc in _circleCache)
{
if (circ.color.CompareTo(cc.Colour) != 0)
{
foundError = true;
}
else
{
// if it matches any one standard, then we can
// stop checking immediately
foundError = false;
break;
}
}

if (foundError)
{
AcStMgr.AcStError error = new AcStMgr.AcStError();
error.Description = "Color is non-standard";
error.BadObjectId = circ.ObjectID;
error.BadObjectName = circ.color.ToString();
error.Plugin = _plugin;
error.ErrorTypeName = "Color ";
error.ResultStatus = AcStMgr.AcStResultStatus.acStResFlagsNone;

if (error.PropertyCount == 0)
{
error.PropertyValuePut("Color", circ.color);
}

_error = error;
foundError = false;
break;
}
_currentIndex++;
}
}
}
}

public void SetContext(object objIdArray, bool bUseDb)
{
_useDb = bUseDb;

if (!bUseDb && objIdArray != null)
{
int[] ids = objIdArray as int[];
_idsToCheck.AddRange(ids);
}
}

public void SetupForAudit(AXDBLib.AcadDatabase pDb, string szPathName,
object stdNameArray, object stdPathArray, object stdDbArray)
{
if (pDb != null)
{
_checkDb = pDb;

if (_checkDb != null)
{
// cache list of all circles in the drawing to check
foreach (AXDBLib.AcadEntity entToCheck in _checkDb.ModelSpace)
{
AXDBLib.AcadCircle circ = entToCheck as AXDBLib.AcadCircle;
if (circ != null)
{
_idsToCheck.Add(circ.ObjectID);
}
}
}

object[] stdDbs = stdDbArray as object[];
string[] stdNames = stdNameArray as string[];
// cache all objects in DWS files we're interested in
// in this case, circles.
for (int i = 0; i < stdDbs.Length; i++)
{
_dwsDb = (AXDBLib.AcadDatabase)stdDbs[i];
foreach (AXDBLib.AcadCircle stdCircle in _dwsDb.ModelSpace)
{
CircleCache cc = new CircleCache();
cc.Radius = stdCircle.Radius;
cc.Colour = stdCircle.color;
cc.StandardFileName = stdNames[i];
AcStMgr.AcStFix fix = new AcStMgr.AcStFix();

fix.Description = "Colour fix";
fix.StandardFileName = cc.StandardFileName;
fix.FixObjectName = "Color: " + stdCircle.color.ToString();

if (fix.PropertyCount == 0)
{
fix.PropertyValuePut("Color", stdCircle.color);
}

cc.Fix = fix;
_circleCache.Add(cc);

fix = null;
cc = null;
}
Marshal.ReleaseComObject(_dwsDb);
_dwsDb = null;
}
}
}

public void StampDatabase(AXDBLib.AcadDatabase pDb, ref bool pStampIt)
{
pStampIt = false;
if (pDb != null)
{
foreach (AXDBLib.AcadEntity dbEnt in pDb.ModelSpace)
{
AXDBLib.AcadCircle circ = dbEnt as AXDBLib.AcadCircle;
if (circ != null)
{
pStampIt = true;
return;
}
}
}
}

public void Start(AcStMgr.AcStError pStartError)
{
if (pStartError != null)
{
int badId = pStartError.BadObjectId;
if (_idsToCheck.Contains(badId))
{
_currentIndex = _idsToCheck.IndexOf(badId);
Next();
}
}
else
{
_currentIndex = -1;
Next();
}
}

public void UpdateStatus(AcStMgr.AcStError pError)
{
// Not implemented yet
}

public string Version
{
get { return _version; }
}

public void WritePluginInfo(object pPluginInfoSectionNode)
{
MSXML2.IXMLDOMNode pSectionNode;
MSXML2.IXMLDOMElement pPluginInfoElement;
MSXML2.IXMLDOMElement xmlElem;

pSectionNode = pPluginInfoSectionNode as MSXML2.IXMLDOMNode;
xmlElem = pSectionNode.ownerDocument.createElement("AcStPluginInfo");
pPluginInfoElement = (MSXML2.IXMLDOMElement)pSectionNode.appendChild(xmlElem);

pPluginInfoElement.setAttribute("PluginName", Name);
pPluginInfoElement.setAttribute("Version", Version);
pPluginInfoElement.setAttribute("Description", Description);
pPluginInfoElement.setAttribute("Author", Author);
pPluginInfoElement.setAttribute("HRef", HRef);
pPluginInfoElement.setAttribute("DWSName", "");
pPluginInfoElement.setAttribute("Status", "1");
}

#endregion
}

[ComVisible(false)]
public class CircleCache
{
public double Radius { get; set; }
public AXDBLib.ACAD_COLOR Colour { get; set; }
public string StandardFileName { get; set; }
public AcStMgr.AcStFix Fix { get; set; }
}
}

I'v done a few things slightly differently to Kean, however the basic gist is still the same.
I will tidy this up a bit once I get my head further into this.

Cheers,
Glenn.

Glenn R

  • Guest
Re: Project-Auditing dwgs to a CAD Standard
« Reply #74 on: August 01, 2008, 09:13:28 AM »
BTW, kean mentions doing this:

Code: [Select]
"regasm /codebase CircleStandard.dll"

whereas, I did this:
Code: [Select]
"regasm /codebase /regfile:FileName CircleStandard.dll"

This outputs the COM registry goo to a reg file and with a change to the codebase entry in the reg file you can park the com binary on another machine and just run the reg file. I thought this might be better for deployment on multiple computers, however I'm only guessing on this point as COM really isn't my thing.

Cheers,
Glenn.