Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#975 new tool pyRevit Health Check #1014

Merged
merged 3 commits into from
Nov 8, 2020

Conversation

davidvadkerti
Copy link
Contributor

I've finally found some time to add the Model Checker tool.
Unfortunatelly I am sure few things are not done the best way. I wrote them also in the comments:

  1. hardcoded list of colors for charts instead of randomize_colors()
  2. error when charts render first time
  3. treating errors when chart data has accented characters - I just tried to remove them by accents2ascii function. I personally think you shouldn't use accented characters in the name of worksets but unfortunatelly in my experience it happens.
  4. help article for bad revit practices - maybe you know more appropriate article
  5. tresholds for parameters are maybe subjective a should be rather configurable?

@eirannejad eirannejad linked an issue Oct 20, 2020 that may be closed by this pull request
@jmcouffin
Copy link
Contributor

The fact that the threshold are hardcoded is an issue. They are very subjective.
It needs to be stored / setup per project or per specs:

  • big,
  • medium,
  • small,
  • tower projects,
  • house projects

Maybe in a separate process. One that you need to launch to setup the threshold choice once for the project. and stored in the project file as a parameter like ThresholdSpecId.

@jmcouffin
Copy link
Contributor

another thing that needs some fixing in the code: you are using the lookup parameter function twice, therefore some of the model check do not work properly when using Revit in another language.

@davidvadkerti
Copy link
Contributor Author

Ok, I will try to fix these issues. Thanks for the review :)

@jmcouffin
Copy link
Contributor

jmcouffin commented Oct 24, 2020 via email

@jmcouffin
Copy link
Contributor

check that in the remarks section.
https://www.revitapidocs.com/2015/4400b9f8-3787-0947-5113-2522ff5e5de2.htm
and this might help as well
https://spiderinnet.typepad.com/blog/2020/05/revit-net-api-get-parameters-from-element.html
and this https://forums.autodesk.com/t5/revit-api-forum/get-parameter-guid-or-lookupparameter-whitch-is-better/td-p/6453524
I tend to use get_Parameter(BuiltinParameterName) method. bullet proof, and does not vary from one language to the other.
I have learnt quite a few tricks looking at your code, nice job!

@jmcouffin
Copy link
Contributor

jmcouffin commented Nov 2, 2020

from line 157:

viewNameString = revit.query.get_name(view)
    # print(viewNameString)
    try:
        if viewNameString[-6:-2] == "Copy" or viewNameString[-4:] == "Copy" or viewNameString[:7] == "Section":

line 334:

    widthFactor = textnote.get_Parameter(DB.BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble()

@davidvadkerti
Copy link
Contributor Author

Thanks for the help, I will try to finally fix it this week.

@jmcouffin
Copy link
Contributor

I just edited the line numbers. I messed up ;p
I still have issues with the draw method for charts with my french sample model
chartCategories.draw()
and
chartFCategories.draw()
It has to do with accents but I don't know precisely where it is not well handled

@davidvadkerti
Copy link
Contributor Author

I have issue drawing the Chart.js chart with any accented values. I think there should be some smarter workaround but I was just happy using my crappy workflow with function removing accents - accents2ascii(string) - line 84

Try to uncomment line 423 if it makes any change:
category = accents2ascii(category) .
I was using it just on revit with english GUI so I havent come across accents in Category.Name yet.

Another issue is filtering out categories which I find not usefull to show. I should probably rather compare BuiltInCategories instead of Category.Names. - line 414

@jmcouffin
Copy link
Contributor

yep the accents issue is huge, the names of parameters also., uncommenting did not work

@jmcouffin
Copy link
Contributor

a text = text.encode(‘utf-8’) would not do the job? (I didn't try it)

@jmcouffin
Copy link
Contributor

graphCatHeadings = [x.encode('UTF8') for x in graphCatHeadings]
add this piece to the puzzle after the graphCatHeadings creation

@jmcouffin
Copy link
Contributor

and

graphFCatData = [x.encode('utf8') for x in graphFCatData]
graphFCatHeadings = [x.encode('utf8') for x in graphFCatHeadings]

after the for loop on # INPLACE CATEGORY GRAPH

Copy link
Contributor

@jmcouffin jmcouffin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added all the stuff I left in the comments. It now works in Revit in French and I am guessing in many other languages

for i in graphFCatHeadings:
count=graphFCatData.count(i)
fCatSet.append(count)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphFCatData = [x.encode('utf8') for x in graphFCatData]
graphFCatHeadings = [x.encode('utf8') for x in graphFCatHeadings]

for i in graphCatHeadings:
count=graphCatData.count(i)
catSet.append(count)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphCatHeadings = [x.encode('UTF8') for x in graphCatHeadings]

for view in view_elements:
viewName = view.LookupParameter('View Name')
try:
viewNameString = viewName.AsString()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

viewNameString = revit.query.get_name(view)

textNoteType_collector = FilteredElementCollector(doc).OfClass(TextNoteType).ToElements()
textnoteWFcount = 0
for textnote in textNoteType_collector:
widthFactor = textnote.LookupParameter('Width Factor').AsDouble()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

widthFactor = textnote.get_Parameter(DB.BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble()

… critical warning list changed to list of GUID, catBanlist changed to list of IDs
'Area is not in a properly enclosed region',
"Rectangular opening doesn't cut its host",
'Elements have duplicate "Number" values',]
# citical warnings Guids
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed Critical warning list to list of GUIDs. Now it is compatible to other laguages than english. I am not sure if there is some better identifier than GUIDs.

# catBanlist = ['Shared Site','Project Information','Structural Load Cases','Sun Path','Color Fill Schema','HVAC Zones','HVAC Load Schedules','Building Type Settings',
# 'Space Type Settings','Survey Point','Project Base Point','Electrical Demand Factor Definitions','Electrical Load Classifications','Panel Schedule Templates - Branch Panel',
# 'Panel Schedule Templates - Data Panel','Panel Schedule Templates - Switchboard','Electrical Load Classification Parameter Element','Automatic Sketch Dimensions',]
catBanlist = [-2000110,-2003101,-2005210,-2009609,-2000552,-2008107,-2008121,-2008120,-2008119,-2001272,-2001271,-2008142,-2008143,-2008145,-2008147,-2008146,-2008148,-2000261,]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catBanlist - list of categories not show is changed to list of category IDs

worksetsSet=[]
for i in worksetNames:
count=graphWorksetsData.count(i)
worksetsSet.append(count)
worksetNames = [x.encode('utf8') for x in worksetNames]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added encoding also for worksets, if there was an accent in Workset name it caused an error

@davidvadkerti
Copy link
Contributor Author

davidvadkerti commented Nov 4, 2020

graphCatHeadings = [x.encode('UTF8') for x in graphCatHeadings]
add this piece to the puzzle after the graphCatHeadings creation

I remember I tried x.encode() not in the list comprehension but inside the loop and it didn't work. I must have done something wrong. Thanks for the correction :)

@davidvadkerti
Copy link
Contributor Author

The fact that the threshold are hardcoded is an issue. They are very subjective.
It needs to be stored / setup per project or per specs:

  • big,
  • medium,
  • small,
  • tower projects,
  • house projects

Maybe in a separate process. One that you need to launch to setup the threshold choice once for the project. and stored in the project file as a parameter like ThresholdSpecId.

I've tested french, czech, russian and japaneese versions of Revit and it seemed the accents issue should be fixed now. But I can't speak these languages except of czech. I've just looked for glitches in the text.

You mentioned I should store threshold values in the project. I was trying to find out how to create new Shared Parameter using Revit API but haven't succeed yet. I've tried to use rsparam module but I've managed just to create new empty Shared Parameter file. Do you have some reference which could I use?

Thanks for the help and for the patience with me :)

@jmcouffin
Copy link
Contributor

That is a great tool that has a great potential and will attract people to pyrevit imho @davidvadkerti

@eirannejad it should have its own push-button visible in the ui, I think

@eirannejad
Copy link
Collaborator

Working on merging the PRs today and publishing the v4.8.4

@eirannejad eirannejad changed the base branch from develop to pr/1014 November 8, 2020 20:29
@eirannejad
Copy link
Collaborator

Merged for review

@eirannejad eirannejad merged commit 25b3478 into pyrevitlabs:pr/1014 Nov 8, 2020
@eirannejad
Copy link
Collaborator

eirannejad commented Nov 9, 2020

@jmcouffin @davidvadkerti Thanks a lot for all the work on this. I merged this for review and ended up combining it with another idea I had that never got around to implement. The Preflight Checks

Switch to the feature/preflight branch to test this feature.


pyRevit extensions, can now define any checks (*_check.py) under the checks/ directory inside the extension. I implemented a new module pyrevit.preflight that collects these checks and can orchestrate their execution. This allows the users to create as many checks as they need in their extensions and automatically incorporate that into the default Preflight Checks tool. It also allows sharing these checks using pyRevit extensions. The Preflight Checks tool will ask the user to run any combination of the available checks.

Run the preflight checks tool from here:

explorer_rL8pOaDNOI

You should see the selection window popup with your test listed in there:

I moved the model checker to extensions/pyRevitTools.extension/checks/modelcheker_check.py for testing. This script defines a check case (derived from pyrevit.preflight.PreflightTestCase) and implements the necessary interface:

class ModelChecker(PreflightTestCase):
    """Revit model quality check"""

    name = "Model Checker"
    author = "David Vadkerti"

    def setUp(self, doc, output):
        pass

    def startTest(self, doc, output):
        timer = coreutils.Timer()
        checkModel(doc, output)
        endtime = timer.get_time()
        endtime_hms = str(datetime.timedelta(seconds=endtime))
        endtime_hms_claim = "Transaction took " + endtime_hms
        print(endtime_hms_claim)

    def tearDown(self, doc, output):
        pass

    def doCleanups(self, doc, output):
        pass

I moved all the test logic tentatively to checkModel() that is being called inside the startTest()

Let's do a good cleanup on this script (split the code into logical functions, comment the code, etc.) and prepare for the feature release 👍

PS
This branch also deprecates the .run extensions and move the Run commands into a commands/ directory inside pyRevit extensions. There is no pyRevitRun.run extension anymore. The example script has been moved to pyRevitTools.extensions/commands/

@eirannejad
Copy link
Collaborator

Let's cleanup the script and I'll improve the Preflight user interface meanwhile. Please checkout this branch, make your changes and send a PR to this branch as well.

@Robbo1234
Copy link

Would it be possible to add the following Preflightchecks?

Location:
Angle to True North
Project Base Point
Survey Point

Files:
Keynote
Shared Parameters

Duplication Marks:

  1. Duplicated Rooms Names
  2. Duplicated Window Names
  3. Duplicated Door Names

Areas:

  1. Not Enclosed Areas
  2. Not Enclosed Rooms
  3. Not Place Areas
  4. Not Placed Rooms
  5. Placed Areas
  6. Placed Room

Links:

  1. Duplication Cads
  2. Imported Cads
  3. Linked DGN's
  4. Linked DWG's
  5. Linked Images
  6. PDF Instance
  7. PDF's
  8. Revit

Misc

  1. Overridden Dimensions
  2. Size of the Revit Model
  3. Owners of the Revit Elements in the Model
  4. Constraint Elements Count

@jmcouffin
Copy link
Contributor

The list in itself makes sense, but it feels like a grocery list anyway.
They are all pretty much possible to implement. Would you help @Robbo1234 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PyRevit Health Check
4 participants